diff options
author | Doug Kearns <dougkearns@gmail.com> | 2009-06-06 03:21:25 +1000 |
---|---|---|
committer | Doug Kearns <dougkearns@gmail.com> | 2009-06-06 03:21:25 +1000 |
commit | 60ae1deb3f732aba8d0578d8d90359d04d928ebf (patch) | |
tree | 6bb41af6fc2db497a73b27f51a3d90041898b4bd /vimperator | |
parent | 29daa12f8ea502dc0518caa87824ced2574a0379 (diff) | |
download | pentadactyl-60ae1deb3f732aba8d0578d8d90359d04d928ebf.tar.gz |
Move {xulmus,vimperator}/**/bookmarks.js to common/content.
Diffstat (limited to 'vimperator')
-rw-r--r-- | vimperator/content/bookmarks.js | 1045 |
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: |