summaryrefslogtreecommitdiff
path: root/common/content/quickmarks.js
diff options
context:
space:
mode:
authorKris Maglione <maglione.k@gmail.com>2009-11-08 20:54:31 -0500
committerKris Maglione <maglione.k@gmail.com>2009-11-08 20:54:31 -0500
commit6a25312c7dbd913322490a6b14674772b3076e63 (patch)
tree8b634b9a6ffaabff3e577c8a2d86289de07b0d36 /common/content/quickmarks.js
parent46b7a29fb71210c51cbff3ad91fd69283d392614 (diff)
downloadpentadactyl-6a25312c7dbd913322490a6b14674772b3076e63.tar.gz
Recfactoring:
* Standard module format. All modules are explicitly declared as modules, they're created via a constructor and instantiated automatically. They're dependency aware. They stringify properly. * Classes are declared the same way (rather like Structs already were). They also stringify properly. Plus, each instance has a rather nifty closure member that closes all of its methods around 'this', so you can pass them to map, forEach, setTimeout, etc. Modules are themselves classes, with a special metaclass, as it were. * Doug Crockford is dead, metaphorically speaking. Closure-based classes just don't fit into any of the common JavaScript frameworks, and they're inefficient and confusing. Now, all class and module members are accessed explicitly via 'this', which makes it very clear that they're class members and not (e.g.) local variables, without anything nasty like Hungarian notation. * Strictly one module per file. Classes that belong to a module live in the same file. * For the moment, there are quite a few utility functions sitting in base.c, because my class implementation used them, and I haven't had the time or inclination to sort them out. I plan to reconcile them with the current mess that is the util namespace. * Changed bracing style.
Diffstat (limited to 'common/content/quickmarks.js')
-rw-r--r--common/content/quickmarks.js173
1 files changed, 173 insertions, 0 deletions
diff --git a/common/content/quickmarks.js b/common/content/quickmarks.js
new file mode 100644
index 00000000..ed0a8e4c
--- /dev/null
+++ b/common/content/quickmarks.js
@@ -0,0 +1,173 @@
+// Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
+//
+// This work is licensed for reuse under an MIT license. Details are
+// given in the LICENSE.txt file included with this file.
+
+/** @scope modules */
+
+/**
+* @instance quickmarks
+*/
+const QuickMarks = Module("quickmarks", {
+ requires: ["storage"],
+
+ init: function () {
+ this._qmarks = storage.newMap("quickmarks", { store: true });
+ },
+
+ /**
+ * Adds a new quickmark with name <b>qmark</b> referencing
+ * the URL <b>location</b>. Any existing quickmark with the same name
+ * will be replaced.
+ *
+ * @param {string} qmark The name of the quickmark {A-Z}.
+ * @param {string} location The URL accessed by this quickmark.
+ */
+ add: function add(qmark, location) {
+ this._qmarks.set(qmark, location);
+ liberator.echomsg("Added Quick Mark '" + qmark + "': " + location, 1);
+ },
+
+ /**
+ * Deletes the specified quickmarks. The <b>filter</b> is a list of
+ * quickmarks and ranges are supported. Eg. "ab c d e-k".
+ *
+ * @param {string} filter The list of quickmarks to delete.
+ *
+ */
+ remove: function remove(filter) {
+ let pattern = RegExp("[" + filter.replace(/\s+/g, "") + "]");
+
+ for (let [qmark, ] in this._qmarks) {
+ if (pattern.test(qmark))
+ this._qmarks.remove(qmark);
+ }
+ },
+
+ /**
+ * Removes all quickmarks.
+ */
+ removeAll: function removeAll() {
+ this._qmarks.clear();
+ },
+
+ /**
+ * Opens the URL referenced by the specified <b>qmark</b>.
+ *
+ * @param {string} qmark The quickmark to open.
+ * @param {number} where A constant describing where to open the page.
+ * See {@link Liberator#open}.
+ */
+ jumpTo: function jumpTo(qmark, where) {
+ let url = this._qmarks.get(qmark);
+
+ if (url)
+ liberator.open(url, where);
+ else
+ liberator.echoerr("E20: QuickMark not set");
+ },
+
+ /**
+ * Lists all quickmarks matching <b>filter</b> in the message window.
+ *
+ * @param {string} filter The list of quickmarks to display. Eg. "abc"
+ * Ranges are not supported.
+ */
+ // FIXME: filter should match that of quickmarks.remove or vice versa
+ list: function list(filter) {
+ let marks = [k for ([k, v] in this._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);
+
+ liberator.assert(marks.length > 0, "No QuickMarks set");
+
+ if (filter.length > 0) {
+ marks = marks.filter(function (qmark) filter.indexOf(qmark) >= 0);
+ liberator.assert(marks.length >= 0, "E283: No QuickMarks matching \"" + filter + "\"");
+ }
+
+ let items = [[mark, this._qmarks.get(mark)] for ([k, mark] in Iterator(marks))];
+ template.genericTable(items, { title: ["QuickMark", "URL"] });
+ }
+}, {
+}, {
+ commands: function () {
+ commands.add(["delqm[arks]"],
+ "Delete the specified QuickMarks",
+ function (args) {
+ // TODO: finish arg parsing - we really need a proper way to do this. :)
+ // assert(args.bang ^ args.string)
+ liberator.assert( args.bang || args.string, "E471: Argument required");
+ liberator.assert(!args.bang || !args.string, "E474: Invalid argument");
+
+ if (args.bang)
+ quickmarks.removeAll();
+ else
+ quickmarks.remove(args.string);
+ },
+ {
+ bang: true,
+ completer: function (context) {
+ context.title = ["QuickMark", "URL"];
+ context.completions = this._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
+ liberator.assert(!args || /[a-zA-Z0-9]/.test(args), "E283: No QuickMarks matching \"" + args + "\"");
+
+ let filter = args.replace(/[^a-zA-Z0-9]/g, "");
+ quickmarks.list(filter);
+ });
+ },
+ mappings: function () {
+ var myModes = config.browserModes;
+
+ mappings.add(myModes,
+ ["go"], "Jump to a QuickMark",
+ function (arg) { quickmarks.jumpTo(arg, liberator.CURRENT_TAB); },
+ { arg: true });
+
+ 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);
+ },
+ { arg: true });
+
+ 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);
+ },
+ { arg: true });
+ },
+});
+
+// vim: set fdm=marker sw=4 ts=4 et: