X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=common%2Fcontent%2Fbookmarks.js;fp=common%2Fcontent%2Fbookmarks.js;h=ca1bdb001d9b3743cf1d2478b7588d20b60e407a;hb=9044153cb63835e39b9de8ec4ade237c03e3888a;hp=1ce6ee11a1bd2ff156ade600f6e8230e218dbcdf;hpb=70740024f9c028c1fd63e1a1850ab062ff956054;p=dactyl.git diff --git a/common/content/bookmarks.js b/common/content/bookmarks.js index 1ce6ee1..ca1bdb0 100644 --- a/common/content/bookmarks.js +++ b/common/content/bookmarks.js @@ -4,9 +4,7 @@ // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. -"use strict"; - -var DEFAULT_FAVICON = "chrome://mozapps/skin/places/defaultFavicon.png"; +/* use strict */ // also includes methods for dealing with keywords and search engines var Bookmarks = Module("bookmarks", { @@ -38,7 +36,7 @@ var Bookmarks = Module("bookmarks", { get format() ({ anchored: false, title: ["URL", "Info"], - keys: { text: "url", description: "title", icon: "icon", extra: "extra", tags: "tags" }, + keys: { text: "url", description: "title", icon: "icon", extra: "extra", tags: "tags", isURI: function () true }, process: [template.icon, template.bookmarkDescription] }), @@ -63,49 +61,54 @@ var Bookmarks = Module("bookmarks", { * Otherwise, if a bookmark for the given URL exists it is * updated instead. * @optional - * @returns {boolean} True if the bookmark was added or updated - * successfully. + * @returns {boolean} True if the bookmark was updated, false if a + * new bookmark was added. */ add: function add(unfiled, title, url, keyword, tags, force) { // FIXME if (isObject(unfiled)) - var { unfiled, title, url, keyword, tags, post, charset, force } = unfiled; - - try { - let uri = util.createURI(url); - if (!force && bookmarkcache.isBookmarked(uri)) - for (var bmark in bookmarkcache) - if (bmark.url == uri.spec) { - if (title) - bmark.title = title; + var { id, unfiled, title, url, keyword, tags, post, charset, force } = unfiled; + + let uri = util.createURI(url); + if (id != null) + var bmark = bookmarkcache.bookmarks[id]; + else if (!force) { + if (keyword && Set.has(bookmarkcache.keywords, keyword)) + bmark = bookmarkcache.keywords[keyword]; + else if (bookmarkcache.isBookmarked(uri)) + for (bmark in bookmarkcache) + if (bmark.url == uri.spec) break; - } + } - if (tags) { - PlacesUtils.tagging.untagURI(uri, null); - PlacesUtils.tagging.tagURI(uri, tags); - } - if (bmark == undefined) - bmark = bookmarkcache.bookmarks[ - services.bookmarks.insertBookmark( - services.bookmarks[unfiled ? "unfiledBookmarksFolder" : "bookmarksMenuFolder"], - uri, -1, title || url)]; - if (!bmark) - return false; - - if (charset !== undefined) - bmark.charset = charset; - if (post !== undefined) - bmark.post = post; - if (keyword) - bmark.keyword = keyword; + if (tags) { + PlacesUtils.tagging.untagURI(uri, null); + PlacesUtils.tagging.tagURI(uri, tags); } - catch (e) { - util.reportError(e); - return false; + + let updated = !!bmark; + if (bmark == undefined) + bmark = bookmarkcache.bookmarks[ + services.bookmarks.insertBookmark( + services.bookmarks[unfiled ? "unfiledBookmarksFolder" : "bookmarksMenuFolder"], + uri, -1, title || url)]; + else { + if (title) + bmark.title = title; + if (!uri.equals(bmark.uri)) + bmark.uri = uri; } - return true; + util.assert(bmark); + + if (charset !== undefined) + bmark.charset = charset; + if (post !== undefined) + bmark.post = post; + if (keyword) + bmark.keyword = keyword; + + return updated; }, /** @@ -116,13 +119,13 @@ var Bookmarks = Module("bookmarks", { */ addSearchKeyword: function addSearchKeyword(elem) { if (elem instanceof HTMLFormElement || elem.form) - var [url, post, charset] = util.parseForm(elem); + var { url, postData, charset } = DOM(elem).formData; else - var [url, post, charset] = [elem.href || elem.src, null, elem.ownerDocument.characterSet]; + var [url, postData, charset] = [elem.href || elem.src, null, elem.ownerDocument.characterSet]; let options = { "-title": "Search " + elem.ownerDocument.title }; - if (post != null) - options["-post"] = post; + if (postData != null) + options["-post"] = postData; if (charset != null && charset !== "UTF-8") options["-charset"] = charset; @@ -163,6 +166,7 @@ var Bookmarks = Module("bookmarks", { let extra = ""; if (title != url) extra = " (" + title + ")"; + this.add({ unfiled: true, title: title, url: url }); dactyl.echomsg({ domains: [util.getHost(url)], message: _("bookmark.added", url + extra) }); } @@ -247,29 +251,49 @@ var Bookmarks = Module("bookmarks", { getSuggestions: function getSuggestions(engineName, query, callback) { const responseType = "application/x-suggestions+json"; + if (Set.has(this.suggestionProviders, engineName)) + return this.suggestionProviders[engineName](query, callback); + let engine = Set.has(this.searchEngines, engineName) && this.searchEngines[engineName]; if (engine && engine.supportsResponseType(responseType)) var queryURI = engine.getSubmission(query, responseType).uri.spec; if (!queryURI) return (callback || util.identity)([]); + function parse(req) JSON.parse(req.responseText)[1].filter(isString); + return this.makeSuggestions(queryURI, parse, callback); + }, + + /** + * Given a query URL, response parser, and optionally a callback, + * fetch and parse search query results for {@link getSuggestions}. + * + * @param {string} url The URL to fetch. + * @param {function(XMLHttpRequest):[string]} parser The function which + * parses the response. + */ + makeSuggestions: function makeSuggestions(url, parser, callback) { function process(req) { let results = []; try { - results = JSON.parse(req.responseText)[1].filter(isString); + results = parser(req); + } + catch (e) { + util.reportError(e); } - catch (e) {} if (callback) return callback(results); return results; } - let req = util.httpGet(queryURI, callback && process); + let req = util.httpGet(url, callback && process); if (callback) return req; return process(req); }, + suggestionProviders: {}, + /** * Returns an array containing a search URL and POST data for the * given search string. If *useDefsearch* is true, the string is @@ -378,14 +402,6 @@ var Bookmarks = Module("bookmarks", { }, { }, { commands: function () { - commands.add(["ju[mps]"], - "Show jumplist", - function () { - let sh = history.session; - commandline.commandOutput(template.jumps(sh.index, sh)); - }, - { argCount: "0" }); - // TODO: Clean this up. const tags = { names: ["-tags", "-T"], @@ -432,15 +448,19 @@ var Bookmarks = Module("bookmarks", { return bookmarks.get(args.join(" "), args["-tags"], null, { keyword: context.filter, title: args["-title"] }); }, type: CommandOption.STRING, - validator: function (arg) /^\S+$/.test(arg) + validator: bind("test", /^\S+$/) }; commands.add(["bma[rk]"], "Add a bookmark", function (args) { + dactyl.assert(!args.bang || args["-id"] == null, + _("bookmark.bangOrID")); + let opts = { force: args.bang, unfiled: false, + id: args["-id"], keyword: args["-keyword"] || null, charset: args["-charset"], post: args["-post"], @@ -449,13 +469,13 @@ var Bookmarks = Module("bookmarks", { url: args.length === 0 ? buffer.uri.spec : args[0] }; - if (bookmarks.add(opts)) { - let extra = (opts.title == opts.url) ? "" : " (" + opts.title + ")"; - dactyl.echomsg({ domains: [util.getHost(opts.url)], message: _("bookmark.added", opts.url + extra) }, - 1, commandline.FORCE_SINGLELINE); - } - else - dactyl.echoerr(_("bookmark.cantAdd", opts.title.quote())); + let updated = bookmarks.add(opts); + let action = updated ? "updated" : "added"; + + let extra = (opts.title == opts.url) ? "" : " (" + opts.title + ")"; + + dactyl.echomsg({ domains: [util.getHost(opts.url)], message: _("bookmark." + action, opts.url + extra) }, + 1, commandline.FORCE_SINGLELINE); }, { argCount: "?", bang: true, @@ -477,6 +497,11 @@ var Bookmarks = Module("bookmarks", { type: CommandOption.STRING, completer: function (context) completion.charset(context), validator: Option.validateCompleter + }, + { + names: ["-id"], + description: "The ID of the bookmark to update", + type: CommandOption.INT } ] }); @@ -553,6 +578,7 @@ var Bookmarks = Module("bookmarks", { if (bmarks.length == 1) { let bmark = bmarks[0]; + options["-id"] = bmark.id; options["-title"] = bmark.title; if (bmark.charset) options["-charset"] = bmark.charset; @@ -627,6 +653,7 @@ var Bookmarks = Module("bookmarks", { context.fork("keyword/" + keyword, keyword.length + space.length, null, function (context) { context.format = history.format; context.title = [/*L*/keyword + " Quick Search"]; + context.keys = { text: "url", description: "title", icon: "icon" }; // context.background = true; context.compare = CompletionContext.Sort.unsorted; context.generate = function () { @@ -663,15 +690,19 @@ var Bookmarks = Module("bookmarks", { let engineList = (engineAliases || options["suggestengines"].join(",") || "google").split(","); engineList.forEach(function (name) { + var desc = name; let engine = bookmarks.searchEngines[name]; - if (!engine) + if (engine) + var desc = engine.description; + else if (!Set.has(bookmarks.suggestionProviders, name)) return; + let [, word] = /^\s*(\S+)/.exec(context.filter) || []; if (!kludge && word == name) // FIXME: Check for matching keywords return; let ctxt = context.fork(name, 0); - ctxt.title = [/*L*/engine.description + " Suggestions"]; + ctxt.title = [/*L*/desc + " Suggestions"]; ctxt.keys = { text: util.identity, description: function () "" }; ctxt.compare = CompletionContext.Sort.unsorted; ctxt.filterFunc = null; @@ -689,9 +720,9 @@ var Bookmarks = Module("bookmarks", { }); }; - completion.addUrlCompleter("S", "Suggest engines", completion.searchEngineSuggest); - completion.addUrlCompleter("b", "Bookmarks", completion.bookmark); - completion.addUrlCompleter("s", "Search engines and keyword URLs", completion.search); + completion.addUrlCompleter("suggestion", "Search engine suggestions", completion.searchEngineSuggest); + completion.addUrlCompleter("bookmark", "Bookmarks", completion.bookmark); + completion.addUrlCompleter("search", "Search engines and keyword URLs", completion.search); } });