summaryrefslogtreecommitdiff
path: root/vimperator
diff options
context:
space:
mode:
authorDoug Kearns <dougkearns@gmail.com>2009-06-06 03:21:25 +1000
committerDoug Kearns <dougkearns@gmail.com>2009-06-06 03:21:25 +1000
commit60ae1deb3f732aba8d0578d8d90359d04d928ebf (patch)
tree6bb41af6fc2db497a73b27f51a3d90041898b4bd /vimperator
parent29daa12f8ea502dc0518caa87824ced2574a0379 (diff)
downloadpentadactyl-60ae1deb3f732aba8d0578d8d90359d04d928ebf.tar.gz
Move {xulmus,vimperator}/**/bookmarks.js to common/content.
Diffstat (limited to 'vimperator')
-rw-r--r--vimperator/content/bookmarks.js1045
1 files changed, 0 insertions, 1045 deletions
diff --git a/vimperator/content/bookmarks.js b/vimperator/content/bookmarks.js
deleted file mode 100644
index 02d2b8d1..00000000
--- a/vimperator/content/bookmarks.js
+++ /dev/null
@@ -1,1045 +0,0 @@
-/***** BEGIN LICENSE BLOCK ***** {{{
-Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
-The contents of this file are subject to the Mozilla Public License Version
-1.1 (the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the
-License.
-
-Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
-
-Alternatively, the contents of this file may be used under the terms of
-either the GNU General Public License Version 2 or later (the "GPL"), or
-the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-in which case the provisions of the GPL or the LGPL are applicable instead
-of those above. If you wish to allow use of your version of this file only
-under the terms of either the GPL or the LGPL, and not to allow others to
-use your version of this file under the terms of the MPL, indicate your
-decision by deleting the provisions above and replace them with the notice
-and other provisions required by the GPL or the LGPL. If you do not delete
-the provisions above, a recipient may use your version of this file under
-the terms of any one of the MPL, the GPL or the LGPL.
-}}} ***** END LICENSE BLOCK *****/
-
-const DEFAULT_FAVICON = "chrome://mozapps/skin/places/defaultFavicon.png";
-
-// Try to import older command line history, quick marks, etc.
-liberator.registerObserver("load", function () {
- if (!options.getPref("extensions.vimperator.commandline_cmd_history"))
- return;
-
- let store = storage["history-command"];
- let pref = options.getPref("extensions.vimperator.commandline_cmd_history");
- for (let [k, v] in Iterator(pref.split("\n")))
- store.push(v);
-
- store = storage["quickmarks"];
- pref = options.getPref("extensions.vimperator.quickmarks")
- .split("\n");
- while (pref.length > 0)
- store.set(pref.shift(), pref.shift());
-
- options.resetPref("extensions.vimperator.commandline_cmd_history");
- options.resetPref("extensions.vimperator.commandline_search_history");
- options.resetPref("extensions.vimperator.quickmarks");
-});
-
-// also includes methods for dealing with keywords and search engines
-function Bookmarks() //{{{
-{
- ////////////////////////////////////////////////////////////////////////////////
- ////////////////////// PRIVATE SECTION /////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- const historyService = PlacesUtils.history;
- const bookmarksService = PlacesUtils.bookmarks;
- const taggingService = PlacesUtils.tagging;
- const faviconService = Cc["@mozilla.org/browser/favicon-service;1"].getService(Ci.nsIFaviconService);
-
- // XXX for strange Firefox bug :(
- // Error: [Exception... "Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [nsIObserverService.addObserver]"
- // nsresult: "0x8000ffff (NS_ERROR_UNEXPECTED)"
- // location: "JS frame :: file://~firefox/components/nsTaggingService.js :: anonymous :: line 89"
- // data: no]
- // Source file: file://~firefox/components/nsTaggingService.js
- taggingService.getTagsForURI(window.makeURI("http://mysterious.bug"), {});
-
- const Bookmark = new Struct("url", "title", "icon", "keyword", "tags", "id");
- const Keyword = new Struct("keyword", "title", "icon", "url");
- Bookmark.defaultValue("icon", function () getFavicon(this.url));
- Bookmark.prototype.__defineGetter__("extra", function () [
- ["keyword", this.keyword, "Keyword"],
- ["tags", this.tags.join(", "), "Tag"]
- ].filter(function (item) item[1]));
-
- const storage = modules.storage;
- function Cache(name, store, serial)
- {
- const rootFolders = [bookmarksService.toolbarFolder, bookmarksService.bookmarksMenuFolder, bookmarksService.unfiledBookmarksFolder];
- const sleep = liberator.sleep;
-
- let bookmarks = [];
- let self = this;
-
- this.__defineGetter__("name", function () name);
- this.__defineGetter__("store", function () store);
- this.__defineGetter__("bookmarks", function () this.load());
-
- this.__defineGetter__("keywords",
- function () [new Keyword(k.keyword, k.title, k.icon, k.url) for each (k in self.bookmarks) if (k.keyword)]);
-
- this.__iterator__ = function () (val for each (val in self.bookmarks));
-
- function loadBookmark(node)
- {
- let uri = util.newURI(node.uri);
- let keyword = bookmarksService.getKeywordForBookmark(node.itemId);
- let tags = taggingService.getTagsForURI(uri, {}) || [];
- let bmark = new Bookmark(node.uri, node.title, node.icon && node.icon.spec, keyword, tags, node.itemId);
-
- bookmarks.push(bmark);
-
- return bmark;
- }
-
- function readBookmark(id)
- {
- return {
- itemId: id,
- uri: bookmarksService.getBookmarkURI(id).spec,
- title: bookmarksService.getItemTitle(id)
- };
- }
-
- function deleteBookmark(id)
- {
- let length = bookmarks.length;
- bookmarks = bookmarks.filter(function (item) item.id != id);
- return bookmarks.length < length;
- }
-
- function findRoot(id)
- {
- do
- {
- var root = id;
- id = bookmarksService.getFolderIdForItem(id);
- } while (id != bookmarksService.placesRoot && id != root);
- return root;
- }
-
- // since we don't use a threaded bookmark loading (by set preload)
- // anymore, is this loading synchronization still needed? --mst
- let loading = false;
- this.load = function load()
- {
- if (loading)
- {
- while (loading)
- sleep(10);
- return bookmarks;
- }
-
- // update our bookmark cache
- bookmarks = [];
- loading = true;
-
- let folders = rootFolders.slice();
- let query = historyService.getNewQuery();
- let options = historyService.getNewQueryOptions();
- while (folders.length > 0)
- {
- query.setFolders(folders, 1);
- folders.shift();
- let result = historyService.executeQuery(query, options);
- let folder = result.root;
- folder.containerOpen = true;
-
- // iterate over the immediate children of this folder
- for (let i = 0; i < folder.childCount; i++)
- {
- let node = folder.getChild(i);
- if (node.type == node.RESULT_TYPE_FOLDER) // folder
- folders.push(node.itemId);
- else if (node.type == node.RESULT_TYPE_URI) // bookmark
- loadBookmark(node);
- }
-
- // close a container after using it!
- folder.containerOpen = false;
- }
- this.__defineGetter__("bookmarks", function () bookmarks);
- loading = false;
- return bookmarks;
- };
-
- var observer = {
- onBeginUpdateBatch: function onBeginUpdateBatch() {},
- onEndUpdateBatch: function onEndUpdateBatch() {},
- onItemVisited: function onItemVisited() {},
- onItemMoved: function onItemMoved() {},
- onItemAdded: function onItemAdded(itemId, folder, index)
- {
- // liberator.dump("onItemAdded(" + itemId + ", " + folder + ", " + index + ")\n");
- if (bookmarksService.getItemType(itemId) == bookmarksService.TYPE_BOOKMARK)
- {
- if (rootFolders.indexOf(findRoot(itemId)) >= 0)
- {
- let bmark = loadBookmark(readBookmark(itemId));
- storage.fireEvent(name, "add", bmark);
- }
- }
- },
- onItemRemoved: function onItemRemoved(itemId, folder, index)
- {
- // liberator.dump("onItemRemoved(" + itemId + ", " + folder + ", " + index + ")\n");
- if (deleteBookmark(itemId))
- storage.fireEvent(name, "remove", itemId);
- },
- onItemChanged: function onItemChanged(itemId, property, isAnnotation, value)
- {
- if (isAnnotation)
- return;
- // liberator.dump("onItemChanged(" + itemId + ", " + property + ", " + value + ")\n");
- let bookmark = bookmarks.filter(function (item) item.id == itemId)[0];
- if (bookmark)
- {
- if (property == "tags")
- value = taggingService.getTagsForURI(util.newURI(bookmark.url), {});
- if (property in bookmark)
- bookmark[property] = value;
- storage.fireEvent(name, "change", itemId);
- }
- },
- QueryInterface: function QueryInterface(iid)
- {
- if (iid.equals(Ci.nsINavBookmarkObserver) || iid.equals(Ci.nsISupports))
- return this;
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
- };
-
- bookmarksService.addObserver(observer, false);
- }
-
- function getFavicon(uri)
- {
- try
- {
- return faviconService.getFaviconImageForPage(util.newURI(uri)).spec;
- }
- catch (e)
- {
- return "";
- }
- }
-
- let bookmarkObserver = function (key, event, arg)
- {
- if (event == "add")
- autocommands.trigger("BookmarkAdd", arg);
- statusline.updateUrl();
- };
-
- var cache = storage.newObject("bookmark-cache", Cache, false);
- storage.addObserver("bookmark-cache", bookmarkObserver, window);
-
- /////////////////////////////////////////////////////////////////////////////}}}
- ////////////////////// OPTIONS /////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- options.add(["defsearch", "ds"],
- "Set the default search engine",
- "string", "google",
- {
- completer: function completer(context)
- {
- completion.search(context, true);
- context.completions = [["", "Don't perform searches by default"]].concat(context.completions);
- },
- validator: Option.validateCompleter
- });
-
- /////////////////////////////////////////////////////////////////////////////}}}
- ////////////////////// MAPPINGS ////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- var myModes = config.browserModes;
-
- mappings.add(myModes, ["a"],
- "Open a prompt to bookmark the current URL",
- function ()
- {
- let title = "";
- if (buffer.title != buffer.URL)
- title = " -title=\"" + buffer.title + "\"";
- commandline.open(":", "bmark " + buffer.URL + title, modes.EX);
- });
-
- mappings.add(myModes, ["A"],
- "Toggle bookmarked state of current URL",
- function () { bookmarks.toggle(buffer.URL); });
-
- /////////////////////////////////////////////////////////////////////////////}}}
- ////////////////////// COMMANDS ////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- commands.add(["ju[mps]"],
- "Show jumplist",
- function ()
- {
- let sh = window.getWebNavigation().sessionHistory;
-
- let entries = [sh.getEntryAtIndex(i, false) for (i in util.range(0, sh.count))];
- let list = template.jumps(sh.index, entries);
- commandline.echo(list, commandline.HL_NORMAL, commandline.FORCE_MULTILINE);
- },
- { argCount: "0" });
-
- // TODO: Clean this up.
- function tags(context, args)
- {
- let filter = context.filter;
- let have = filter.split(",");
-
- args.completeFilter = have.pop();
-
- let prefix = filter.substr(0, filter.length - args.completeFilter.length);
- let tags = util.Array.uniq(util.Array.flatten([b.tags for ([k, b] in Iterator(cache.bookmarks))]));
-
- return [[prefix + tag, tag] for ([i, tag] in Iterator(tags)) if (have.indexOf(tag) < 0)];
- }
-
- function title(context, args)
- {
- if (!args.bang)
- return [[content.document.title, "Current Page Title"]];
- context.keys.text = "title";
- context.keys.description = "url";
- return bookmarks.get(args.join(" "), args["-tags"], null, { keyword: args["-keyword"], title: context.filter });
- }
-
- function keyword(context, args)
- {
- if (!args.bang)
- return [];
- context.keys.text = "keyword";
- return bookmarks.get(args.join(" "), args["-tags"], null, { keyword: context.filter, title: args["-title"] });
- }
-
- commands.add(["bma[rk]"],
- "Add a bookmark",
- function (args)
- {
- let url = args.length == 0 ? buffer.URL : args[0];
- let title = args["-title"] || (args.length == 0 ? buffer.title : null);
- let keyword = args["-keyword"] || null;
- let tags = args["-tags"] || [];
-
- if (bookmarks.add(false, title, url, keyword, tags, args.bang))
- {
- let extra = (title == url) ? "" : " (" + title + ")";
- liberator.echomsg("Added bookmark: " + url + extra, 1, commandline.FORCE_SINGLELINE);
- }
- else
- liberator.echoerr("Exxx: Could not add bookmark `" + title + "'", commandline.FORCE_SINGLELINE);
- },
- {
- argCount: "?",
- bang: true,
- completer: function (context, args)
- {
- if (!args.bang)
- {
- context.completions = [[content.document.documentURI, "Current Location"]];
- return;
- }
- completion.bookmark(context, args["-tags"], { keyword: args["-keyword"], title: args["-title"] });
- },
- options: [[["-title", "-t"], commands.OPTION_STRING, null, title],
- [["-tags", "-T"], commands.OPTION_LIST, null, tags],
- [["-keyword", "-k"], commands.OPTION_STRING, function (arg) /\w/.test(arg)]]
- });
-
- commands.add(["bmarks"],
- "List or open multiple bookmarks",
- function (args)
- {
- bookmarks.list(args.join(" "), args["-tags"] || [], args.bang, args["-max"]);
- },
- {
- bang: true,
- completer: function completer(context, args)
- {
- context.quote = null;
- context.filter = args.join(" ");
- completion.bookmark(context, args["-tags"]);
- },
- options: [[["-tags", "-T"], commands.OPTION_LIST, null, tags],
- [["-max", "-m"], commands.OPTION_INT]]
- });
-
- commands.add(["delbm[arks]"],
- "Delete a bookmark",
- function (args)
- {
- let url = args.string || buffer.URL;
- let deletedCount = bookmarks.remove(url);
-
- liberator.echomsg(deletedCount + " bookmark(s) with url `" + url + "' deleted", 1, commandline.FORCE_SINGLELINE);
- },
- {
- argCount: "?",
- completer: function completer(context) completion.bookmark(context),
- literal: 0
- });
-
- /////////////////////////////////////////////////////////////////////////////}}}
- ////////////////////// PUBLIC SECTION //////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- return {
-
- get format() ({
- anchored: false,
- title: ["URL", "Info"],
- keys: { text: "url", description: "title", icon: "icon", extra: "extra", tags: "tags" },
- process: [template.icon, template.bookmarkDescription]
- }),
-
- // if "bypassCache" is true, it will force a reload of the bookmarks database
- // on my PC, it takes about 1ms for each bookmark to load, so loading 1000 bookmarks
- // takes about 1 sec
- get: function get(filter, tags, maxItems, extra)
- {
- return completion.runCompleter("bookmark", filter, maxItems, tags, extra);
- },
-
- // if starOnly = true it is saved in the unfiledBookmarksFolder, otherwise in the bookmarksMenuFolder
- add: function add(starOnly, title, url, keyword, tags, force)
- {
- try
- {
- let uri = util.createURI(url);
- if (!force)
- {
- for (let bmark in cache)
- {
- if (bmark[0] == uri.spec)
- {
- var id = bmark[5];
- if (title)
- bookmarksService.setItemTitle(id, title);
- break;
- }
- }
- }
- if (id == undefined)
- id = bookmarksService.insertBookmark(
- bookmarksService[starOnly ? "unfiledBookmarksFolder" : "bookmarksMenuFolder"],
- uri, -1, title || url);
- if (!id)
- return false;
-
- if (keyword)
- bookmarksService.setKeywordForBookmark(id, keyword);
- if (tags)
- taggingService.tagURI(uri, tags);
- }
- catch (e)
- {
- liberator.log(e, 0);
- return false;
- }
-
- return true;
- },
-
- toggle: function toggle(url)
- {
- if (!url)
- return;
-
- let count = this.remove(url);
- if (count > 0)
- commandline.echo("Removed bookmark: " + url, commandline.HL_NORMAL, commandline.FORCE_SINGLELINE);
- else
- {
- let title = buffer.title || url;
- let extra = "";
- if (title != url)
- extra = " (" + title + ")";
- this.add(true, title, url);
- commandline.echo("Added bookmark: " + url + extra, commandline.HL_NORMAL, commandline.FORCE_SINGLELINE);
- }
- },
-
- isBookmarked: function isBookmarked(url)
- {
- try
- {
- let uri = util.newURI(url);
- return (bookmarksService.getBookmarkedURIFor(uri) != null);
- }
- catch (e)
- {
- return false;
- }
- },
-
- // returns number of deleted bookmarks
- remove: function remove(url)
- {
- if (!url)
- return 0;
-
- let i = 0;
- try
- {
- let uri = util.newURI(url);
- var count = {};
- let bmarks = bookmarksService.getBookmarkIdsForURI(uri, count);
-
- for (; i < bmarks.length; i++)
- bookmarksService.removeItem(bmarks[i]);
- }
- catch (e)
- {
- liberator.log(e, 0);
- return i;
- }
-
- // update the display of our "bookmarked" symbol
- statusline.updateUrl();
-
- return count.value;
- },
-
- getFavicon: function (url) getFavicon(url),
-
- // TODO: add filtering
- // also ensures that each search engine has a Vimperator-friendly alias
- getSearchEngines: function getSearchEngines()
- {
- let searchEngines = [];
- let firefoxEngines = services.get("browserSearch").getVisibleEngines({});
- for (let [,engine] in Iterator(firefoxEngines))
- {
- let alias = engine.alias;
- if (!alias || !/^[a-z0-9_-]+$/.test(alias))
- alias = engine.name.replace(/^\W*([a-zA-Z_-]+).*/, "$1").toLowerCase();
- if (!alias)
- alias = "search"; // for search engines which we can't find a suitable alias
-
- // make sure we can use search engines which would have the same alias (add numbers at the end)
- let newAlias = alias;
- for (let j = 1; j <= 10; j++) // <=10 is intentional
- {
- if (!searchEngines.some(function (item) item[0] == newAlias))
- break;
-
- newAlias = alias + j;
- }
- // only write when it changed, writes are really slow
- if (engine.alias != newAlias)
- engine.alias = newAlias;
-
- searchEngines.push([engine.alias, engine.description, engine.iconURI && engine.iconURI.spec]);
- }
-
- return searchEngines;
- },
-
- getSuggestions: function getSuggestions(engineName, query, callback)
- {
- const responseType = "application/x-suggestions+json";
-
- let engine = services.get("browserSearch").getEngineByAlias(engineName);
- if (engine && engine.supportsResponseType(responseType))
- var queryURI = engine.getSubmission(query, responseType).uri.spec;
- if (!queryURI)
- return [];
-
- function process(resp)
- {
- let results = [];
- try
- {
- results = services.get("json").decode(resp.responseText)[1];
- results = [[item, ""] for ([k, item] in Iterator(results)) if (typeof item == "string")];
- }
- catch (e) {}
- if (!callback)
- return results;
- callback(results);
- }
-
- let resp = util.httpGet(queryURI, callback && process);
- if (!callback)
- return process(resp);
- },
-
- // TODO: add filtering
- // format of returned array:
- // [keyword, helptext, url]
- getKeywords: function getKeywords()
- {
- return cache.keywords;
- },
-
- // full search string including engine name as first word in @param text
- // if @param useDefSearch is true, it uses the default search engine
- // @returns the url for the search string
- // if the search also requires a postData, [url, postData] is returned
- getSearchURL: function getSearchURL(text, useDefsearch)
- {
- let url = null;
- let postData = {};
- let searchString = (useDefsearch ? options["defsearch"] + " " : "") + text;
-
- // we need to make sure our custom alias have been set, even if the user
- // did not :open <tab> once before
- this.getSearchEngines();
-
- url = window.getShortcutOrURI(searchString, postData);
- if (url == searchString)
- url = null;
-
- if (postData && postData.value)
- return [url, postData.value];
- else
- return url; // can be null
- },
-
- // if openItems is true, open the matching bookmarks items in tabs rather than display
- list: function list(filter, tags, openItems, maxItems)
- {
- // FIXME: returning here doesn't make sense
- // Why the hell doesn't it make sense? --Kris
- // Because it unconditionally bypasses the final error message
- // block and does so only when listing items, not opening them. In
- // short it breaks the :bmarks command which doesn't make much
- // sense to me but I'm old-fashioned. --djk
- if (!openItems)
- return completion.listCompleter("bookmark", filter, maxItems, tags);
- let items = completion.runCompleter("bookmark", filter, maxItems, tags);
-
- if (items.length)
- return liberator.open(items.map(function (i) i.url), liberator.NEW_TAB);
-
- if (filter.length > 0 && tags.length > 0)
- liberator.echoerr("E283: No bookmarks matching tags: \"" + tags + "\" and string: \"" + filter + "\"");
- else if (filter.length > 0)
- liberator.echoerr("E283: No bookmarks matching string: \"" + filter + "\"");
- else if (tags.length > 0)
- liberator.echoerr("E283: No bookmarks matching tags: \"" + tags + "\"");
- else
- liberator.echoerr("No bookmarks set");
- }
- };
- //}}}
-}; //}}}
-
-function History() //{{{
-{
- ////////////////////////////////////////////////////////////////////////////////
- ////////////////////// PRIVATE SECTION /////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- const historyService = PlacesUtils.history;
-
- /////////////////////////////////////////////////////////////////////////////}}}
- ////////////////////// MAPPINGS ////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- var myModes = config.browserModes;
-
- mappings.add(myModes,
- ["<C-o>"], "Go to an older position in the jump list",
- function (count) { history.stepTo(-Math.max(count, 1)); },
- { flags: Mappings.flags.COUNT });
-
- mappings.add(myModes,
- ["<C-i>"], "Go to a newer position in the jump list",
- function (count) { history.stepTo(Math.max(count, 1)); },
- { flags: Mappings.flags.COUNT });
-
- mappings.add(myModes,
- ["H", "<A-Left>", "<M-Left>"], "Go back in the browser history",
- function (count) { history.stepTo(-Math.max(count, 1)); },
- { flags: Mappings.flags.COUNT });
-
- mappings.add(myModes,
- ["L", "<A-Right>", "<M-Right>"], "Go forward in the browser history",
- function (count) { history.stepTo(Math.max(count, 1)); },
- { flags: Mappings.flags.COUNT });
-
- /////////////////////////////////////////////////////////////////////////////}}}
- ////////////////////// COMMANDS ////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- commands.add(["ba[ck]"],
- "Go back in the browser history",
- function (args)
- {
- let url = args.literalArg;
-
- if (args.bang)
- history.goToStart();
- else
- {
- if (url)
- {
- let sh = window.getWebNavigation().sessionHistory;
- for (let i in util.range(sh.index, 0, -1))
- {
- if (sh.getEntryAtIndex(i, false).URI.spec == url)
- {
- window.getWebNavigation().gotoIndex(i);
- return;
- }
- }
- liberator.echoerr("Exxx: URL not found in history");
- }
- else
- history.stepTo(-Math.max(args.count, 1));
- }
- },
- {
- argCount: "?",
- bang: true,
- completer: function completer(context)
- {
- let sh = window.getWebNavigation().sessionHistory;
-
- context.anchored = false;
- context.completions = [sh.getEntryAtIndex(i, false) for (i in util.range(sh.index, 0, -1))];
- context.keys = { text: function (item) item.URI.spec, description: "title" };
- context.compare = CompletionContext.Sort.unsorted;
- },
- count: true,
- literal: 0
- });
-
- commands.add(["fo[rward]", "fw"],
- "Go forward in the browser history",
- function (args)
- {
- let url = args.literalArg;
-
- if (args.bang)
- history.goToEnd();
- else
- {
- if (url)
- {
- let sh = window.getWebNavigation().sessionHistory;
- for (let i in util.range(sh.index + 1, sh.count))
- {
- if (sh.getEntryAtIndex(i, false).URI.spec == url)
- {
- window.getWebNavigation().gotoIndex(i);
- return;
- }
- }
- liberator.echoerr("Exxx: URL not found in history");
- }
- else
- history.stepTo(Math.max(args.count, 1));
- }
- },
- {
- argCount: "?",
- bang: true,
- completer: function completer(context)
- {
- let sh = window.getWebNavigation().sessionHistory;
-
- context.anchored = false;
- context.completions = [sh.getEntryAtIndex(i, false) for (i in util.range(sh.index + 1, sh.count))];
- context.keys = { text: function (item) item.URI.spec, description: "title" };
- context.compare = CompletionContext.Sort.unsorted;
- },
- count: true,
- literal: 0
- });
-
- commands.add(["hist[ory]", "hs"],
- "Show recently visited URLs",
- function (args) { history.list(args.join(" "), args.bang, args["-max"] || 1000); },
- {
- bang: true,
- completer: function (context) { context.quote = null; completion.history(context); },
- // completer: function (filter) completion.history(filter)
- options: [[["-max", "-m"], options.OPTION_INT]]
- });
-
- /////////////////////////////////////////////////////////////////////////////}}}
- ////////////////////// PUBLIC SECTION //////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- return {
-
- get format() bookmarks.format,
-
- get service() historyService,
-
- get: function get(filter, maxItems)
- {
- // no query parameters will get all history
- let query = historyService.getNewQuery();
- let options = historyService.getNewQueryOptions();
-
- if (typeof filter == "string")
- filter = { searchTerms: filter };
- for (let [k, v] in Iterator(filter))
- query[k] = v;
- options.sortingMode = options.SORT_BY_DATE_DESCENDING;
- options.resultType = options.RESULTS_AS_URI;
- if (maxItems > 0)
- options.maxResults = maxItems;
-
- // execute the query
- let root = historyService.executeQuery(query, options).root;
- root.containerOpen = true;
- let items = util.map(util.range(0, root.childCount), function (i) {
- let node = root.getChild(i);
- return {
- url: node.uri,
- title: node.title,
- icon: node.icon ? node.icon.spec : DEFAULT_FAVICON
- };
- });
- root.containerOpen = false; // close a container after using it!
-
- return items;
- },
-
- // TODO: better names
- stepTo: function stepTo(steps)
- {
- let start = 0;
- let end = window.getWebNavigation().sessionHistory.count - 1;
- let current = window.getWebNavigation().sessionHistory.index;
-
- if (current == start && steps < 0 || current == end && steps > 0)
- liberator.beep();
- else
- {
- let index = util.Math.constrain(current + steps, start, end);
- window.getWebNavigation().gotoIndex(index);
- }
- },
-
- goToStart: function goToStart()
- {
- let index = window.getWebNavigation().sessionHistory.index;
-
- if (index > 0)
- window.getWebNavigation().gotoIndex(0);
- else
- liberator.beep();
-
- },
-
- goToEnd: function goToEnd()
- {
- let sh = window.getWebNavigation().sessionHistory;
- let max = sh.count - 1;
-
- if (sh.index < max)
- window.getWebNavigation().gotoIndex(max);
- else
- liberator.beep();
-
- },
-
- // if openItems is true, open the matching history items in tabs rather than display
- list: function list(filter, openItems, maxItems)
- {
- // FIXME: returning here doesn't make sense
- // Why the hell doesn't it make sense? --Kris
- // See comment at bookmarks.list --djk
- if (!openItems)
- return completion.listCompleter("history", filter, maxItems);
- let items = completion.runCompleter("history", filter, maxItems);
-
- if (items.length)
- return liberator.open(items.map(function (i) i.url), liberator.NEW_TAB);
-
- if (filter.length > 0)
- liberator.echoerr("E283: No history matching \"" + filter + "\"");
- else
- liberator.echoerr("No history set");
- }
- };
- //}}}
-}; //}}}
-
-function QuickMarks() //{{{
-{
- ////////////////////////////////////////////////////////////////////////////////
- ////////////////////// PRIVATE SECTION /////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- var qmarks = storage.newMap("quickmarks", true);
-
- /////////////////////////////////////////////////////////////////////////////}}}
- ////////////////////// MAPPINGS ////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- var myModes = config.browserModes;
-
- mappings.add(myModes,
- ["go"], "Jump to a QuickMark",
- function (arg) { quickmarks.jumpTo(arg, liberator.CURRENT_TAB); },
- { flags: Mappings.flags.ARGUMENT });
-
- mappings.add(myModes,
- ["gn"], "Jump to a QuickMark in a new tab",
- function (arg)
- {
- quickmarks.jumpTo(arg,
- /\bquickmark\b/.test(options["activate"]) ?
- liberator.NEW_TAB : liberator.NEW_BACKGROUND_TAB);
- },
- { flags: Mappings.flags.ARGUMENT });
-
- mappings.add(myModes,
- ["M"], "Add new QuickMark for current URL",
- function (arg)
- {
- if (/[^a-zA-Z0-9]/.test(arg))
- return void liberator.beep();
-
- quickmarks.add(arg, buffer.URL);
- },
- { flags: Mappings.flags.ARGUMENT });
-
- /////////////////////////////////////////////////////////////////////////////}}}
- ////////////////////// COMMANDS ////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- commands.add(["delqm[arks]"],
- "Delete the specified QuickMarks",
- function (args)
- {
- // TODO: finish arg parsing - we really need a proper way to do this. :)
- if (!args.bang && !args.string)
- return void liberator.echoerr("E471: Argument required");
-
- if (args.bang && args.string)
- return void liberator.echoerr("E474: Invalid argument");
-
- if (args.bang)
- quickmarks.removeAll();
- else
- quickmarks.remove(args.string);
- },
- {
- bang: true,
- completer: function (context)
- {
- context.title = ["QuickMark", "URL"];
- context.completions = qmarks;
- }
- });
-
- commands.add(["qma[rk]"],
- "Mark a URL with a letter for quick access",
- function (args)
- {
- let matches = args.string.match(/^([a-zA-Z0-9])(?:\s+(.+))?$/);
- if (!matches)
- liberator.echoerr("E488: Trailing characters");
- else if (!matches[2])
- quickmarks.add(matches[1], buffer.URL);
- else
- quickmarks.add(matches[1], matches[2]);
- },
- { argCount: "+" });
-
- commands.add(["qmarks"],
- "Show all QuickMarks",
- function (args)
- {
- args = args.string;
-
- // ignore invalid qmark characters unless there are no valid qmark chars
- if (args && !/[a-zA-Z0-9]/.test(args))
- return void liberator.echoerr("E283: No QuickMarks matching \"" + args + "\"");
-
- let filter = args.replace(/[^a-zA-Z0-9]/g, "");
- quickmarks.list(filter);
- });
-
- /////////////////////////////////////////////////////////////////////////////}}}
- ////////////////////// PUBLIC SECTION //////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- return {
-
- add: function add(qmark, location)
- {
- qmarks.set(qmark, location);
- liberator.echomsg("Added Quick Mark '" + qmark + "': " + location, 1);
- },
-
- remove: function remove(filter)
- {
- let pattern = RegExp("[" + filter.replace(/\s+/g, "") + "]");
-
- for (let [qmark,] in qmarks)
- {
- if (pattern.test(qmark))
- qmarks.remove(qmark);
- }
- },
-
- removeAll: function removeAll()
- {
- qmarks.clear();
- },
-
- jumpTo: function jumpTo(qmark, where)
- {
- let url = qmarks.get(qmark);
-
- if (url)
- liberator.open(url, where);
- else
- liberator.echoerr("E20: QuickMark not set");
- },
-
- list: function list(filter)
- {
- let marks = [k for ([k, v] in qmarks)];
- let lowercaseMarks = marks.filter(function (x) /[a-z]/.test(x)).sort();
- let uppercaseMarks = marks.filter(function (x) /[A-Z]/.test(x)).sort();
- let numberMarks = marks.filter(function (x) /[0-9]/.test(x)).sort();
-
- marks = Array.concat(lowercaseMarks, uppercaseMarks, numberMarks);
-
- if (marks.length == 0)
- return void liberator.echoerr("No QuickMarks set");
-
- if (filter.length > 0)
- {
- marks = marks.filter(function (qmark) filter.indexOf(qmark) >= 0);
- if (marks.length == 0)
- return void liberator.echoerr("E283: No QuickMarks matching \"" + filter + "\"");
- }
-
- let items = [[mark, qmarks.get(mark)] for ([k, mark] in Iterator(marks))];
- template.genericTable(items, { title: ["QuickMark", "URL"] });
- }
- };
- //}}}
-}; //}}}
-
-// vim: set fdm=marker sw=4 ts=4 et: