// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
-// Copyright (c) 2008-2013 Kris Maglione <maglione.k at Gmail>
+// Copyright (c) 2008-2014 Kris Maglione <maglione.k at Gmail>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
lazyRequire("io", ["io"]);
lazyRequire("finder", ["RangeFind"]);
lazyRequire("overlay", ["overlay"]);
+lazyRequire("promises", ["Promise", "promises"]);
lazyRequire("sanitizer", ["sanitizer"]);
lazyRequire("storage", ["File", "storage"]);
lazyRequire("template", ["template"]);
let win = services.focus.focusedWindow;
if (!win || win == window || util.topWindow(win) != window)
- return window.content
+ return window.content;
if (win.top == window)
return win;
return win.top;
this.win = win;
},
- get addPageInfoSection() Buffer.closure.addPageInfoSection,
+ get addPageInfoSection() Buffer.bound.addPageInfoSection,
get pageInfo() Buffer.pageInfo,
*/
get alternateStyleSheets() {
let stylesheets = array.flatten(
- this.allFrames().map(function (w) Array.slice(w.document.styleSheets)));
+ this.allFrames().map(w => Array.slice(w.document.styleSheets)));
return stylesheets.filter(
- function (stylesheet) /^(screen|all|)$/i.test(stylesheet.media.mediaText) && !/^\s*$/.test(stylesheet.title)
+ s => /^(screen|all|)$/i.test(s.media.mediaText) && !/^\s*$/.test(s.title)
);
},
+ /**
+ * The load context of the window bound to this buffer.
+ */
+ get loadContext() sanitizer.getContext(this.win),
+
+ /**
+ * Content preference methods.
+ */
+ prefs: Class.Memoize(function ()
+ let (self = this) ({
+ /**
+ * Returns a promise for the given preference name.
+ *
+ * @param {string} pref The name of the preference to return.
+ * @returns {Promise<*>}
+ */
+ get: promises.withCallbacks(function get([resolve, reject], pref) {
+ let val = services.contentPrefs.getCachedByDomainAndName(
+ self.uri.spec, pref, self.loadContext);
+
+ let found = false;
+ if (val)
+ resolve(val.value);
+ else
+ services.contentPrefs.getByDomainAndName(
+ self.uri.spec, pref, self.loadContext,
+ { handleCompletion: () => {
+ if (!found)
+ resolve(undefined);
+ },
+ handleResult: (pref) => {
+ found = true;
+ resolve(pref.value);
+ },
+ handleError: reject });
+ }),
+
+ /**
+ * Sets a content preference for the given buffer.
+ *
+ * @param {string} pref The preference to set.
+ * @param {string} value The value to store.
+ */
+ set: promises.withCallbacks(function set([resolve, reject], pref, value) {
+ services.contentPrefs.set(
+ self.uri.spec, pref, value, self.loadContext,
+ { handleCompletion: () => {},
+ handleResult: resolve,
+ handleError: reject });
+ }),
+
+ /**
+ * Clear a content preference for the given buffer.
+ *
+ * @param {string} pref The preference to clear.
+ */
+ clear: promises.withCallbacks(function clear([resolve, reject], pref) {
+ services.contentPrefs.removeByDomainAndName(
+ self.uri.spec, pref, self.loadContext,
+ { handleCompletion: () => {},
+ handleResult: resolve,
+ handleError: reject });
+ })
+ })),
+
/**
* Gets a content preference for the given buffer.
*
* @returns {string|number|boolean} The value of the preference, if
* callback is not provided.
*/
- getPref: function getPref(pref, callback) {
- // God damn it.
- if (config.haveGecko("19.0a1"))
- services.contentPrefs.getPref(this.uri, pref,
- sanitizer.getContext(this.win), callback);
- else
- services.contentPrefs.getPref(uri, pref, callback);
- },
+ getPref: deprecated("prefs.get", function getPref(pref, callback) {
+ services.contentPrefs.getPref(this.uri, pref,
+ this.loadContext, callback);
+ }),
/**
* Sets a content preference for the given buffer.
* @param {string} pref The preference to set.
* @param {string} value The value to store.
*/
- setPref: function setPref(pref, value) {
+ setPref: deprecated("prefs.set", function setPref(pref, value) {
services.contentPrefs.setPref(
- this.uri, pref, value, sanitizer.getContext(this.win));
- },
+ this.uri, pref, value, this.loadContext);
+ }),
/**
* Clear a content preference for the given buffer.
*
* @param {string} pref The preference to clear.
*/
- clearPref: function clearPref(pref) {
+ clearPref: deprecated("prefs.clear", function clearPref(pref) {
services.contentPrefs.removePref(
- this.uri, pref, sanitizer.getContext(this.win));
- },
+ this.uri, pref, this.loadContext);
+ }),
climbUrlPath: function climbUrlPath(count) {
let { dactyl } = this.modules;
*/
get loaded() Math.min.apply(null,
this.allFrames()
- .map(function (frame) ["loading", "interactive", "complete"]
- .indexOf(frame.document.readyState))),
+ .map(frame => ["loading", "interactive", "complete"]
+ .indexOf(frame.document.readyState))),
/**
* @property {Object} The local state store for the currently selected
*/
get zoomLevel() {
let v = this.contentViewer;
- return v[v.textZoom == 1 ? "fullZoom" : "textZoom"] * 100
+ return v[v.textZoom == 1 ? "fullZoom" : "textZoom"] * 100;
},
set zoomLevel(value) { this.setZoom(value, this.fullZoom); },
})(win || this.win);
if (focusedFirst)
- return frames.filter(function (f) f === this.focusedFrame, this).concat(
- frames.filter(function (f) f !== this.focusedFrame, this));
+ return frames.filter(f => f === this.focusedFrame).concat(
+ frames.filter(f => f !== this.focusedFrame));
return frames;
},
yield elem;
function a(regexp, elem) regexp.test(elem.textContent) === regexp.result ||
- Array.some(elem.childNodes, function (child) regexp.test(child.alt) === regexp.result);
+ Array.some(elem.childNodes,
+ child => (regexp.test(child.alt) === regexp.result));
+
function b(regexp, elem) regexp.test(elem.title) === regexp.result;
let res = Array.filter(frame.document.querySelectorAll(selector), Hints.isVisible);
};
DOM(elem).mousedown(params).mouseup(params);
- if (!config.haveGecko("2b"))
- DOM(elem).click(params);
let sel = util.selectionController(win);
sel.getSelection(sel.SELECTION_FOCUS_REGION).collapseToStart();
function getRanges(rect) {
let nodes = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils)
.nodesFromRect(rect.x, rect.y, 0, rect.width, rect.height, 0, false, false);
- return Array.filter(nodes, function (n) n instanceof Ci.nsIDOMText)
+ return Array.filter(nodes, n => n instanceof Ci.nsIDOMText)
.map(RangeFind.nodeContents);
}
rect = { x: w / 3, y: 0, width: w / 3, height: win.innerHeight };
}
- var reduce = function (a, b) DOM(a).rect.top < DOM(b).rect.top ? a : b;
+ var reduce = (a, b) => DOM(a).rect.top < DOM(b).rect.top ? a : b;
var dir = "forward";
var y = 0;
if (reverse) {
- reduce = function (a, b) DOM(b).rect.bottom > DOM(a).rect.bottom ? b : a;
+ reduce = (a, b) => DOM(b).rect.bottom > DOM(a).rect.bottom ? b : a;
dir = "backward";
y = win.innerHeight - 1;
}
get shortURL() {
let { uri, doc } = this;
- for each (let shortener in Buffer.uriShorteners)
+ function hashify(url) {
+ let newURI = util.newURI(url);
+
+ if (uri.hasRef && !newURI.hasRef)
+ newURI.ref = uri.ref;
+
+ return newURI.spec;
+ }
+
+ for (let shortener of Buffer.uriShorteners)
try {
let shortened = shortener(uri, doc);
if (shortened)
- return shortened.spec;
+ return hashify(shortened.spec);
}
catch (e) {
util.reportError(e);
}
let link = DOM("link[href][rev=canonical], \
- link[href][rel=shortlink]", doc);
+ link[href][rel=shortlink]", doc)
+ .attr("href");
if (link)
- return link.attr("href");
+ return hashify(link);
return null;
},
* vertical percentages. See {@link Buffer.scrollToPercent} for
* parameters.
*/
- scrollToPercent: function scrollToPercent(horizontal, vertical)
- Buffer.scrollToPercent(this.findScrollable(0, vertical == null), horizontal, vertical),
+ scrollToPercent: function scrollToPercent(horizontal, vertical, dir)
+ Buffer.scrollToPercent(this.findScrollable(dir || 0, vertical == null), horizontal, vertical),
/**
* Scrolls the currently active element to the given horizontal and
* @param {number} count The multiple of 'scroll' lines to scroll.
* @optional
*/
- scrollByScrollSize: function scrollByScrollSize(direction, count) {
+ scrollByScrollSize: function scrollByScrollSize(direction, count=1) {
let { options } = this.modules;
direction = direction ? 1 : -1;
- count = count || 1;
if (options["scroll"] > 0)
this.scrollVertical("lines", options["scroll"] * direction);
let path = options["jumptags"][arg];
util.assert(path, _("error.invalidArgument", arg));
- let distance = reverse ? function (rect) -rect.top : function (rect) rect.top;
- let elems = [[e, distance(e.getBoundingClientRect())] for (e in path.matcher(this.focusedFrame.document))]
- .filter(function (e) e[1] > FUDGE)
- .sort(function (a, b) a[1] - b[1])
+ let distance = reverse ? rect => -rect.top
+ : rect => rect.top;
+
+ let elems = [[e, distance(e.getBoundingClientRect())]
+ for (e in path.matcher(this.focusedFrame.document))]
+ .filter(e => e[1] > FUDGE)
+ .sort((a, b) => a[1] - b[1]);
if (offScreen && !reverse)
elems = elems.filter(function (e) e[1] > this, this.topWindow.innerHeight);
return;
// remove all hidden frames
- frames = frames.filter(function (frame) !(frame.document.body instanceof Ci.nsIDOMHTMLFrameSetElement))
- .filter(function (frame) !frame.frameElement ||
+ frames = frames.filter(frame => !(frame.document.body instanceof Ci.nsIDOMHTMLFrameSetElement))
+ .filter(frame => !frame.frameElement ||
let (rect = frame.frameElement.getBoundingClientRect())
rect.width && rect.height);
showPageInfo: function showPageInfo(verbose, sections) {
let { commandline, dactyl, options } = this.modules;
- let self = this;
-
// Ctrl-g single line output
if (!verbose) {
let file = this.win.location.pathname.split("/").pop() || _("buffer.noName");
let info = template.map(
(sections || options["pageinfo"])
- .map(function (opt) Buffer.pageInfo[opt].action.call(self)),
- function (res) res && iter(res).join(", ") || undefined,
+ .map((opt) => Buffer.pageInfo[opt].action.call(this)),
+ res => (res && iter(res).join(", ") || undefined),
", ").join("");
if (bookmarkcache.isBookmarked(this.URL))
return;
}
- let list = template.map(sections || options["pageinfo"], function (option) {
+ let list = template.map(sections || options["pageinfo"], (option) => {
let { action, title } = Buffer.pageInfo[option];
- return template.table(title, action.call(self, true));
+ return template.table(title, action.call(this, true));
}, ["br"]);
commandline.commandOutput(list);
else {
let url = loc || doc.location.href;
const PREFIX = "view-source:";
- if (url.indexOf(PREFIX) == 0)
+ if (url.startsWith(PREFIX))
url = url.substr(PREFIX.length);
else
url = PREFIX + url;
let ext = uri.fileExtension || "txt";
if (doc.contentType)
- ext = services.mime.getPrimaryExtension(doc.contentType, ext);
+ try {
+ ext = services.mime.getPrimaryExtension(doc.contentType, ext);
+ }
+ catch (e) {}
if (!isString(doc))
return io.withTempFiles(function (temp) {
if (prefs.get("browser.zoom.siteSpecific")) {
var privacy = sanitizer.getContext(this.win);
if (value == 1) {
- this.clearPref("browser.content.full-zoom");
- this.clearPref("dactyl.content.full-zoom");
+ this.prefs.clear("browser.content.full-zoom");
+ this.prefs.clear("dactyl.content.full-zoom");
}
else {
- this.setPref("browser.content.full-zoom", value);
- this.setPref("dactyl.content.full-zoom", fullZoom);
+ this.prefs.set("browser.content.full-zoom", value);
+ this.prefs.set("dactyl.content.full-zoom", fullZoom);
}
}
/**
* Updates the zoom level of this buffer from a content preference.
*/
- updateZoom: util.wrapCallback(function updateZoom() {
- let self = this;
+ updateZoom: promises.task(function updateZoom() {
let uri = this.uri;
if (prefs.get("browser.zoom.siteSpecific")) {
- this.getPref("dactyl.content.full-zoom", function (val) {
- if (val != null && uri.equals(self.uri) && val != prefs.get("browser.zoom.full"))
- [self.contentViewer.textZoom, self.contentViewer.fullZoom] =
- [self.contentViewer.fullZoom, self.contentViewer.textZoom];
- });
+ let val = yield this.prefs.get("dactyl.content.full-zoom");
+
+ if (val != null && uri.equals(this.uri) && val != prefs.get("browser.zoom.full"))
+ [this.contentViewer.textZoom, this.contentViewer.fullZoom] =
+ [this.contentViewer.fullZoom, this.contentViewer.textZoom];
}
}),
get scrollRightMax() this.win.scrollMaxY,
get scrollLeft() this.win.scrollX,
- set scrollLeft(val) { this.win.scrollTo(val, this.win.scrollY) },
+ set scrollLeft(val) { this.win.scrollTo(val, this.win.scrollY); },
get scrollTop() this.win.scrollY,
- set scrollTop(val) { this.win.scrollTo(this.win.scrollX, val) }
+ set scrollTop(val) { this.win.scrollTo(this.win.scrollX, val); }
};
return elem;
},
names.push([decodeURIComponent(url.replace(/.*?([^\/]*)\/*$/, "$1")),
_("buffer.save.filename")]);
- return names.filter(function ([leaf, title]) leaf)
- .map(function ([leaf, title]) [leaf.replace(config.OS.illegalCharacters, encodeURIComponent)
- .replace(re, ext), title]);
+ return names.filter(([leaf, title]) => leaf)
+ .map(([leaf, title]) => [leaf.replace(config.OS.illegalCharacters, encodeURIComponent)
+ .replace(re, ext), title]);
},
findScrollableWindow: deprecated("buffer.findScrollableWindow", function findScrollableWindow()
return elem[pos] > 0;
let max = pos + "Max";
- if (max in elem && pos > 0)
- return elem[pos] < elem[max];
+ if (max in elem) {
+ if (elem[pos] < elem[max])
+ return true;
+ if (dir > 0)
+ return false;
+ return elem[pos] > 0;
+ }
let style = DOM(elem).style;
let borderSize = Math.round(parseFloat(style[border1]) + parseFloat(style[border2]));
* Like scrollTo, but scrolls more smoothly and does not update
* marks.
*/
- smoothScrollTo: function smoothScrollTo(node, x, y) {
+ smoothScrollTo: let (timers = WeakMap())
+ function smoothScrollTo(node, x, y) {
let { options } = overlay.activeModules;
let time = options["scrolltime"];
let elem = Buffer.Scrollable(node);
- if (node.dactylScrollTimer)
- node.dactylScrollTimer.cancel();
+ if (timers.has(node))
+ timers.get(node).cancel();
if (x == null)
x = elem.scrollLeft;
else {
elem.scrollLeft = startX + (x - startX) / steps * n;
elem.scrollTop = startY + (y - startY) / steps * n;
- node.dactylScrollTimer = util.timeout(next, time / steps);
+ timers.set(node, util.timeout(next, time / steps));
}
}).call(this);
},
return {
x: elem.scrollLeft && elem.scrollLeft / this._exWidth(node),
y: elem.scrollTop / parseFloat(style.lineHeight)
- }
+ };
},
_exWidth: function _exWidth(elem) {
let arg = args[0];
// FIXME: arg handling is a bit of a mess, check for filename
- dactyl.assert(!arg || arg[0] == ">" && !config.OS.isWindows,
+ dactyl.assert(!arg || arg[0] == ">",
_("error.trailingCharacters"));
const PRINTER = "PostScript/default";
const BRANCH = "printer_" + PRINTER + ".";
const BRANCHES = ["print.", BRANCH, "print." + BRANCH];
function set(pref, value) {
- BRANCHES.forEach(function (branch) { prefs.set(branch + pref, value) });
+ BRANCHES.forEach(function (branch) { prefs.set(branch + pref, value); });
}
- prefs.withContext(function () {
- if (arg) {
- prefs.set("print.print_printer", PRINTER);
+ let settings = services.printSettings.newPrintSettings;
+ settings.printSilent = args.bang;
+ if (arg) {
+ settings.printToFile = true;
+ settings.toFileName = io.File(arg.substr(1)).path;
+ settings.outputFormat = settings.kOutputFormatPDF;
- set("print_to_file", true);
- set("print_to_filename", io.File(arg.substr(1)).path);
-
- dactyl.echomsg(_("print.toFile", arg.substr(1)));
- }
- else
- dactyl.echomsg(_("print.sending"));
+ dactyl.echomsg(_("print.toFile", arg.substr(1)));
+ }
+ else {
+ dactyl.echomsg(_("print.sending"));
- prefs.set("print.always_print_silent", args.bang);
if (false)
prefs.set("print.show_print_progress", !args.bang);
+ }
- config.browser.contentWindow.print();
- });
+ config.browser.contentWindow
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebBrowserPrint).print(settings, null);
dactyl.echomsg(_("print.sent"));
},
function (args) {
let arg = args[0] || "";
- let titles = buffer.alternateStyleSheets.map(function (stylesheet) stylesheet.title);
+ let titles = buffer.alternateStyleSheets.map(sheet => sheet.title);
dactyl.assert(!arg || titles.indexOf(arg) >= 0,
_("error.invalidArgument", arg));
events: function initEvents(dactyl, modules, window) {
let { buffer, config, events } = modules;
- events.listen(config.browser, "scroll", buffer.closure._updateBufferPosition, false);
+ events.listen(config.browser, "scroll", buffer.bound._updateBufferPosition, false);
},
mappings: function initMappings(dactyl, modules, window) {
let { Editor, Events, buffer, editor, events, ex, mappings, modes, options, tabs } = modules;
mappings.add([modes.NORMAL],
["<C-a>", "<increment-url-path>"], "Increment last number in URL",
- function (args) { buffer.incrementURL(Math.max(args.count, 1)); },
+ function ({ count }) { buffer.incrementURL(Math.max(count, 1)); },
{ count: true });
mappings.add([modes.NORMAL],
["<C-x>", "<decrement-url-path>"], "Decrement last number in URL",
- function (args) { buffer.incrementURL(-Math.max(args.count, 1)); },
+ function ({ count }) { buffer.incrementURL(-Math.max(count, 1)); },
{ count: true });
mappings.add([modes.NORMAL], ["gu", "<open-parent-path>"],
"Go to parent directory",
- function (args) { buffer.climbUrlPath(Math.max(args.count, 1)); },
+ function ({ count }) { buffer.climbUrlPath(Math.max(count, 1)); },
{ count: true });
mappings.add([modes.NORMAL], ["gU", "<open-root-path>"],
mappings.add([modes.COMMAND], [".", "<repeat-key>"],
"Repeat the last key event",
- function (args) {
+ function ({ count }) {
if (mappings.repeat) {
- for (let i in util.interruptibleRange(0, Math.max(args.count, 1), 100))
+ for (let i in util.interruptibleRange(0, Math.max(count, 1), 100))
mappings.repeat();
}
},
// scrolling
mappings.add([modes.NORMAL], ["j", "<Down>", "<C-e>", "<scroll-down-line>"],
"Scroll document down",
- function (args) { buffer.scrollVertical("lines", Math.max(args.count, 1)); },
+ function ({ count }) { buffer.scrollVertical("lines", Math.max(count, 1)); },
{ count: true });
mappings.add([modes.NORMAL], ["k", "<Up>", "<C-y>", "<scroll-up-line>"],
"Scroll document up",
- function (args) { buffer.scrollVertical("lines", -Math.max(args.count, 1)); },
+ function ({ count }) { buffer.scrollVertical("lines", -Math.max(count, 1)); },
{ count: true });
mappings.add([modes.NORMAL], dactyl.has("mail") ? ["h", "<scroll-left-column>"] : ["h", "<Left>", "<scroll-left-column>"],
"Scroll document to the left",
- function (args) { buffer.scrollHorizontal("columns", -Math.max(args.count, 1)); },
+ function ({ count }) { buffer.scrollHorizontal("columns", -Math.max(count, 1)); },
{ count: true });
mappings.add([modes.NORMAL], dactyl.has("mail") ? ["l", "<scroll-right-column>"] : ["l", "<Right>", "<scroll-right-column>"],
"Scroll document to the right",
- function (args) { buffer.scrollHorizontal("columns", Math.max(args.count, 1)); },
+ function ({ count }) { buffer.scrollHorizontal("columns", Math.max(count, 1)); },
{ count: true });
mappings.add([modes.NORMAL], ["0", "^", "<scroll-begin>"],
mappings.add([modes.NORMAL], ["gg", "<Home>", "<scroll-top>"],
"Go to the top of the document",
- function (args) { buffer.scrollToPercent(null, args.count != null ? args.count : 0); },
+ function ({ count }) { buffer.scrollToPercent(null, count != null ? count : 0,
+ count != null ? 0 : -1); },
{ count: true });
mappings.add([modes.NORMAL], ["G", "<End>", "<scroll-bottom>"],
"Go to the end of the document",
- function (args) {
- if (args.count)
+ function ({ count }) {
+ if (count)
var elem = options.get("linenumbers")
.getLine(buffer.focusedFrame.document,
- args.count);
+ count);
if (elem)
elem.scrollIntoView(true);
- else if (args.count)
- buffer.scrollToPosition(null, args.count);
+ else if (count)
+ buffer.scrollToPosition(null, count);
else
- buffer.scrollToPercent(null, 100);
+ buffer.scrollToPercent(null, 100, 1);
},
{ count: true });
mappings.add([modes.NORMAL], ["%", "<scroll-percent>"],
"Scroll to {count} percent of the document",
- function (args) {
- dactyl.assert(args.count > 0 && args.count <= 100);
- buffer.scrollToPercent(null, args.count);
+ function ({ count }) {
+ dactyl.assert(count > 0 && count <= 100);
+ buffer.scrollToPercent(null, count);
},
{ count: true });
mappings.add([modes.NORMAL], ["<C-d>", "<scroll-down>"],
"Scroll window downwards in the buffer",
- function (args) { buffer._scrollByScrollSize(args.count, true); },
+ function ({ count }) { buffer._scrollByScrollSize(count, true); },
{ count: true });
mappings.add([modes.NORMAL], ["<C-u>", "<scroll-up>"],
"Scroll window upwards in the buffer",
- function (args) { buffer._scrollByScrollSize(args.count, false); },
+ function ({ count }) { buffer._scrollByScrollSize(count, false); },
{ count: true });
mappings.add([modes.NORMAL], ["<C-b>", "<PageUp>", "<S-Space>", "<scroll-up-page>"],
"Scroll up a full page",
- function (args) { buffer.scrollVertical("pages", -Math.max(args.count, 1)); },
+ function ({ count }) { buffer.scrollVertical("pages", -Math.max(count, 1)); },
{ count: true });
mappings.add([modes.NORMAL], ["<Space>"],
"Scroll down a full page",
- function (args) {
+ function ({ count }) {
if (isinstance((services.focus.focusedWindow || buffer.win).document.activeElement,
[Ci.nsIDOMHTMLInputElement,
Ci.nsIDOMHTMLButtonElement,
Ci.nsIDOMXULButtonElement]))
return Events.PASS;
- buffer.scrollVertical("pages", Math.max(args.count, 1));
+ buffer.scrollVertical("pages", Math.max(count, 1));
},
{ count: true });
mappings.add([modes.NORMAL], ["<C-f>", "<PageDown>", "<scroll-down-page>"],
"Scroll down a full page",
- function (args) { buffer.scrollVertical("pages", Math.max(args.count, 1)); },
+ function ({ count }) { buffer.scrollVertical("pages", Math.max(count, 1)); },
{ count: true });
mappings.add([modes.NORMAL], ["]f", "<previous-frame>"],
"Focus next frame",
- function (args) { buffer.shiftFrameFocus(Math.max(args.count, 1)); },
+ function ({ count }) { buffer.shiftFrameFocus(Math.max(count, 1)); },
{ count: true });
mappings.add([modes.NORMAL], ["[f", "<next-frame>"],
"Focus previous frame",
- function (args) { buffer.shiftFrameFocus(-Math.max(args.count, 1)); },
+ function ({ count }) { buffer.shiftFrameFocus(-Math.max(count, 1)); },
{ count: true });
mappings.add([modes.NORMAL], ["["],
"Jump to the previous element as defined by 'jumptags'",
- function (args) { buffer.findJump(args.arg, args.count, true); },
+ function ({ arg, count }) { buffer.findJump(arg, count, true); },
{ arg: true, count: true });
mappings.add([modes.NORMAL], ["g]"],
"Jump to the next off-screen element as defined by 'jumptags'",
- function (args) { buffer.findJump(args.arg, args.count, false, true); },
+ function ({ arg, count }) { buffer.findJump(arg, count, false, true); },
{ arg: true, count: true });
mappings.add([modes.NORMAL], ["]"],
"Jump to the next element as defined by 'jumptags'",
- function (args) { buffer.findJump(args.arg, args.count, false); },
+ function ({ arg, count }) { buffer.findJump(arg, count, false); },
{ arg: true, count: true });
mappings.add([modes.NORMAL], ["{"],
"Jump to the previous paragraph",
- function (args) { buffer.findJump("p", args.count, true); },
+ function ({ count }) { buffer.findJump("p", count, true); },
{ count: true });
mappings.add([modes.NORMAL], ["}"],
"Jump to the next paragraph",
- function (args) { buffer.findJump("p", args.count, false); },
+ function ({ count }) { buffer.findJump("p", count, false); },
{ count: true });
mappings.add([modes.NORMAL], ["]]", "<next-page>"],
"Follow the link labeled 'next' or '>' if it exists",
- function (args) {
- buffer.findLink("next", options["nextpattern"], (args.count || 1) - 1, true);
+ function ({ count }) {
+ buffer.findLink("next", options["nextpattern"], (count || 1) - 1, true);
},
{ count: true });
mappings.add([modes.NORMAL], ["[[", "<previous-page>"],
"Follow the link labeled 'prev', 'previous' or '<' if it exists",
- function (args) {
- buffer.findLink("prev", options["previouspattern"], (args.count || 1) - 1, true);
+ function ({ count }) {
+ buffer.findLink("prev", options["previouspattern"], (count || 1) - 1, true);
},
{ count: true });
mappings.add([modes.NORMAL], ["gi", "<focus-input>"],
"Focus last used input field",
- function (args) {
+ function ({ count }) {
let elem = buffer.lastInputField;
- if (args.count >= 1 || !elem || !events.isContentNode(elem)) {
+ if (count >= 1 || !elem || !events.isContentNode(elem)) {
let xpath = ["frame", "iframe", "input", "xul:textbox", "textarea[not(@disabled) and not(@readonly)]"];
let frames = buffer.allFrames(null, true);
- let elements = array.flatten(frames.map(function (win) [m for (m in DOM.XPath(xpath, win.document))]))
+ let elements = array.flatten(frames.map(win => [m for (m in DOM.XPath(xpath, win.document))]))
.filter(function (elem) {
if (isinstance(elem, [Ci.nsIDOMHTMLFrameElement,
Ci.nsIDOMHTMLIFrameElement]))
elem = DOM(elem);
- if (elem[0].readOnly || !DOM(elem).isEditable)
+ if (elem[0].readOnly || elem[0].disabled || !DOM(elem).isEditable)
return false;
let style = elem.style;
});
dactyl.assert(elements.length > 0);
- elem = elements[Math.constrain(args.count, 1, elements.length) - 1];
+ elem = elements[Math.constrain(count, 1, elements.length) - 1];
}
buffer.focusElement(elem);
DOM(elem).scrollIntoView();
// zooming
mappings.add([modes.NORMAL], ["zi", "+", "<text-zoom-in>"],
"Enlarge text zoom of current web page",
- function (args) { buffer.zoomIn(Math.max(args.count, 1), false); },
+ function ({ count }) { buffer.zoomIn(Math.max(count, 1), false); },
{ count: true });
mappings.add([modes.NORMAL], ["zm", "<text-zoom-more>"],
"Enlarge text zoom of current web page by a larger amount",
- function (args) { buffer.zoomIn(Math.max(args.count, 1) * 3, false); },
+ function ({ count }) { buffer.zoomIn(Math.max(count, 1) * 3, false); },
{ count: true });
mappings.add([modes.NORMAL], ["zo", "-", "<text-zoom-out>"],
"Reduce text zoom of current web page",
- function (args) { buffer.zoomOut(Math.max(args.count, 1), false); },
+ function ({ count }) { buffer.zoomOut(Math.max(count, 1), false); },
{ count: true });
mappings.add([modes.NORMAL], ["zr", "<text-zoom-reduce>"],
"Reduce text zoom of current web page by a larger amount",
- function (args) { buffer.zoomOut(Math.max(args.count, 1) * 3, false); },
+ function ({ count }) { buffer.zoomOut(Math.max(count, 1) * 3, false); },
{ count: true });
mappings.add([modes.NORMAL], ["zz", "<text-zoom>"],
"Set text zoom value of current web page",
- function (args) { buffer.setZoom(args.count > 1 ? args.count : 100, false); },
+ function ({ count }) { buffer.setZoom(count > 1 ? count : 100, false); },
{ count: true });
mappings.add([modes.NORMAL], ["ZI", "zI", "<full-zoom-in>"],
"Enlarge full zoom of current web page",
- function (args) { buffer.zoomIn(Math.max(args.count, 1), true); },
+ function ({ count }) { buffer.zoomIn(Math.max(count, 1), true); },
{ count: true });
mappings.add([modes.NORMAL], ["ZM", "zM", "<full-zoom-more>"],
"Enlarge full zoom of current web page by a larger amount",
- function (args) { buffer.zoomIn(Math.max(args.count, 1) * 3, true); },
+ function ({ count }) { buffer.zoomIn(Math.max(count, 1) * 3, true); },
{ count: true });
mappings.add([modes.NORMAL], ["ZO", "zO", "<full-zoom-out>"],
"Reduce full zoom of current web page",
- function (args) { buffer.zoomOut(Math.max(args.count, 1), true); },
+ function ({ count }) { buffer.zoomOut(Math.max(count, 1), true); },
{ count: true });
mappings.add([modes.NORMAL], ["ZR", "zR", "<full-zoom-reduce>"],
"Reduce full zoom of current web page by a larger amount",
- function (args) { buffer.zoomOut(Math.max(args.count, 1) * 3, true); },
+ function ({ count }) { buffer.zoomOut(Math.max(count, 1) * 3, true); },
{ count: true });
mappings.add([modes.NORMAL], ["zZ", "<full-zoom>"],
"Set full zoom value of current web page",
- function (args) { buffer.setZoom(args.count > 1 ? args.count : 100, true); },
+ function ({ count }) { buffer.setZoom(count > 1 ? count : 100, true); },
{ count: true });
// page info
return vals;
},
validator: function (value) DOM.validateMatcher.call(this, value)
- && Object.keys(value).every(function (v) v.length == 1)
+ && Object.keys(value).every(v => v.length == 1)
});
options.add(["linenumbers", "ln"],
if (/^func:/.test(filter.result))
var res = dactyl.userEval("(" + Option.dequote(filter.result.substr(5)) + ")")(doc, line);
else
- res = iter.nth(filter.matcher(doc),
- function (elem) (elem.nodeValue || elem.textContent).trim() == line && DOM(elem).display != "none",
- 0)
+ res = iter.find(filter.matcher(doc),
+ elem => ((elem.nodeValue || elem.textContent).trim() == line &&
+ DOM(elem).display != "none"))
|| iter.nth(filter.matcher(doc), util.identity, line - 1);
if (res)
break;
// get meta tag data, sort and put into pageMeta[]
let metaNodes = this.focusedFrame.document.getElementsByTagName("meta");
- return Array.map(metaNodes, function (node) [(node.name || node.httpEquiv),
- template.highlightURL(node.content)])
- .sort(function (a, b) util.compareIgnoreCase(a[0], b[0]));
+ return Array.map(metaNodes, node => [(node.name || node.httpEquiv),
+ template.highlightURL(node.content)])
+ .sort((a, b) => util.compareIgnoreCase(a[0], b[0]));
});
Buffer.addPageInfoSection("s", "Security", function (verbose) {
- let { statusline } = this.modules
+ let { statusline } = this.modules;
let identity = this.topWindow.gIdentityHandler;
yield ["Verified by", data.caOrg];
- if (identity._overrideService.hasMatchingOverride(identity._lastLocation.hostname,
- (identity._lastLocation.port || 443),
- data.cert, {}, {}))
+ let { host, port } = identity._lastUri;
+ if (port == -1)
+ port = 443;
+
+ if (identity._overrideService.hasMatchingOverride(host, port, data.cert, {}, {}))
yield ["User exception", /*L*/"true"];
break;
}
});
+// internal navigation doesn't currently update link[rel='shortlink']
+Buffer.addURIShortener("youtube.com", (uri, doc) => {
+ let video = array.toObject(uri.query.split("&")
+ .map(p => p.split("="))).v;
+ return video ? util.newURI("http://youtu.be/" + video) : null;
+});
+
// catch(e){ if (!e.stack) e = Error(e); dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack); }
endModule();
-// vim: set fdm=marker sw=4 ts=4 et ft=javascript:
+// vim: set fdm=marker sw=4 sts=4 ts=8 et ft=javascript: