1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-19 23:07:58 +01:00

Move DOM and config properties from the util namespace to the DOM and config namespaces, respectively.

This commit is contained in:
Kris Maglione
2011-08-14 23:30:05 -04:00
parent 236a894c89
commit 681af3e618
19 changed files with 719 additions and 594 deletions

View File

@@ -116,13 +116,13 @@ var Bookmarks = Module("bookmarks", {
*/ */
addSearchKeyword: function addSearchKeyword(elem) { addSearchKeyword: function addSearchKeyword(elem) {
if (elem instanceof HTMLFormElement || elem.form) if (elem instanceof HTMLFormElement || elem.form)
var [url, post, charset] = util.parseForm(elem); var { url, postData, charset } = DOM(elem).formData;
else 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 }; let options = { "-title": "Search " + elem.ownerDocument.title };
if (post != null) if (postData != null)
options["-post"] = post; options["-postData"] = postData;
if (charset != null && charset !== "UTF-8") if (charset != null && charset !== "UTF-8")
options["-charset"] = charset; options["-charset"] = charset;

View File

@@ -16,7 +16,6 @@
*/ */
var Buffer = Module("buffer", { var Buffer = Module("buffer", {
init: function init() { init: function init() {
this.evaluateXPath = util.evaluateXPath;
this.pageInfo = {}; this.pageInfo = {};
this.addPageInfoSection("e", "Search Engines", function (verbose) { this.addPageInfoSection("e", "Search Engines", function (verbose) {
@@ -24,8 +23,8 @@ var Buffer = Module("buffer", {
let n = 1; let n = 1;
let nEngines = 0; let nEngines = 0;
for (let { document: doc } in values(buffer.allFrames())) { for (let { document: doc } in values(buffer.allFrames())) {
let engines = util.evaluateXPath(["link[@href and @rel='search' and @type='application/opensearchdescription+xml']"], doc); let engines = DOM("link[href][rel=search][type='application/opensearchdescription+xml']", doc);
nEngines += engines.snapshotLength; nEngines += engines.length;
if (verbose) if (verbose)
for (let link in engines) for (let link in engines)
@@ -79,7 +78,7 @@ var Buffer = Module("buffer", {
for (let [i, win] in Iterator(buffer.allFrames())) { for (let [i, win] in Iterator(buffer.allFrames())) {
let doc = win.document; let doc = win.document;
for (let link in util.evaluateXPath(["link[@href and (@rel='feed' or (@rel='alternate' and @type))]"], doc)) { for (let link in DOM("link[href][rel=feed], link[href][rel=alternate][type]", doc)) {
let rel = link.rel.toLowerCase(); let rel = link.rel.toLowerCase();
let feed = { title: link.title, href: link.href, type: link.type || "" }; let feed = { title: link.title, href: link.href, type: link.type || "" };
if (isValidFeed(feed, doc.nodePrincipal, rel == "feed")) { if (isValidFeed(feed, doc.nodePrincipal, rel == "feed")) {
@@ -612,7 +611,7 @@ var Buffer = Module("buffer", {
}; };
DOM(elem).mousedown(params).mouseup(params); DOM(elem).mousedown(params).mouseup(params);
if (!util.haveGecko("2b")) if (!config.haveGecko("2b"))
DOM(elem).click(params); DOM(elem).click(params);
let sel = util.selectionController(win); let sel = util.selectionController(win);
@@ -855,7 +854,7 @@ var Buffer = Module("buffer", {
dactyl.assert(idx in elems); dactyl.assert(idx in elems);
let elem = elems[idx][0]; let elem = elems[idx][0];
elem.scrollIntoView(true); DOM(elem).scrollIntoView();
let sel = elem.ownerDocument.defaultView.getSelection(); let sel = elem.ownerDocument.defaultView.getSelection();
sel.removeAllRanges(); sel.removeAllRanges();
@@ -897,7 +896,7 @@ var Buffer = Module("buffer", {
// focus next frame and scroll into view // focus next frame and scroll into view
dactyl.focus(frames[next]); dactyl.focus(frames[next]);
if (frames[next] != content) if (frames[next] != content)
frames[next].frameElement.scrollIntoView(false); DOM(frames[next].frameElement).scrollIntoView();
// add the frame indicator // add the frame indicator
let doc = frames[next].document; let doc = frames[next].document;
@@ -1207,7 +1206,7 @@ var Buffer = Module("buffer", {
selection.removeAllRanges(); selection.removeAllRanges();
selection.addRange(range); selection.addRange(range);
} }
return util.domToString(range); return DOM.stringify(range);
}, },
getDefaultNames: function getDefaultNames(node) { getDefaultNames: function getDefaultNames(node) {
@@ -1242,7 +1241,7 @@ var Buffer = Module("buffer", {
names.push([decodeURIComponent(url.replace(/.*?([^\/]*)\/*$/, "$1")), "File Name"]); names.push([decodeURIComponent(url.replace(/.*?([^\/]*)\/*$/, "$1")), "File Name"]);
return names.filter(function ([leaf, title]) leaf) return names.filter(function ([leaf, title]) leaf)
.map(function ([leaf, title]) [leaf.replace(util.OS.illegalCharacters, encodeURIComponent) .map(function ([leaf, title]) [leaf.replace(config.OS.illegalCharacters, encodeURIComponent)
.replace(re, ext), title]); .replace(re, ext), title]);
}, },
@@ -1256,7 +1255,7 @@ var Buffer = Module("buffer", {
pos = "scrollLeft", size = "clientWidth", max = "scrollWidth", layoutSize = "offsetWidth", pos = "scrollLeft", size = "clientWidth", max = "scrollWidth", layoutSize = "offsetWidth",
overflow = "overflowX", border1 = "borderLeftWidth", border2 = "borderRightWidth"; overflow = "overflowX", border1 = "borderLeftWidth", border2 = "borderRightWidth";
let style = util.computedStyle(elem); let style = DOM(elem).style;
let borderSize = Math.round(parseFloat(style[border1]) + parseFloat(style[border2])); let borderSize = Math.round(parseFloat(style[border1]) + parseFloat(style[border2]));
let realSize = elem[size]; let realSize = elem[size];
// Stupid Gecko eccentricities. May fail for quirks mode documents. // Stupid Gecko eccentricities. May fail for quirks mode documents.
@@ -1288,7 +1287,7 @@ var Buffer = Module("buffer", {
if (top != null) if (top != null)
elem.scrollTop = top; elem.scrollTop = top;
if (util.haveGecko("2.0") && !util.haveGecko("7.*")) if (config.haveGecko("2.0") && !util.haveGecko("7.*"))
elem.ownerDocument.defaultView elem.ownerDocument.defaultView
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils) .QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils)
.redraw(); .redraw();
@@ -1307,7 +1306,7 @@ var Buffer = Module("buffer", {
* given direction. * given direction.
*/ */
scrollHorizontal: function scrollHorizontal(elem, unit, number) { scrollHorizontal: function scrollHorizontal(elem, unit, number) {
let fontSize = parseInt(util.computedStyle(elem).fontSize); let fontSize = parseInt(DOM(elem).style.fontSize);
let increment; let increment;
if (unit == "columns") if (unit == "columns")
increment = fontSize; // Good enough, I suppose. increment = fontSize; // Good enough, I suppose.
@@ -1337,7 +1336,7 @@ var Buffer = Module("buffer", {
* given direction. * given direction.
*/ */
scrollVertical: function scrollVertical(elem, unit, number) { scrollVertical: function scrollVertical(elem, unit, number) {
let fontSize = parseInt(util.computedStyle(elem).lineHeight); let fontSize = parseInt(DOM(elem).style.lineHeight);
let increment; let increment;
if (unit == "lines") if (unit == "lines")
increment = fontSize; increment = fontSize;
@@ -1385,7 +1384,7 @@ var Buffer = Module("buffer", {
* column ordinal to scroll to. * column ordinal to scroll to.
*/ */
scrollToPosition: function scrollToPosition(elem, horizontal, vertical) { scrollToPosition: function scrollToPosition(elem, horizontal, vertical) {
let style = util.computedStyle(elem); let style = DOM(elem).style;
Buffer.scrollTo(elem, Buffer.scrollTo(elem,
horizontal == null ? null : horizontal == null ? null :
horizontal == 0 ? 0 : this._exWidth(elem) * horizontal, horizontal == 0 ? 0 : this._exWidth(elem) * horizontal,
@@ -1399,7 +1398,7 @@ var Buffer = Module("buffer", {
* @param {Element} elem The element to scroll. * @param {Element} elem The element to scroll.
*/ */
getScrollPosition: function getPosition(elem) { getScrollPosition: function getPosition(elem) {
let style = util.computedStyle(elem); let style = DOM(elem).style;
return { return {
x: elem.scrollLeft && elem.scrollLeft / this._exWidth(elem), x: elem.scrollLeft && elem.scrollLeft / this._exWidth(elem),
y: elem.scrollTop / parseFloat(style.lineHeight) y: elem.scrollTop / parseFloat(style.lineHeight)
@@ -1407,14 +1406,13 @@ var Buffer = Module("buffer", {
}, },
_exWidth: function _exWidth(elem) { _exWidth: function _exWidth(elem) {
let div = elem.appendChild( let div = DOM(<elem style="width: 1ex !important; position: absolute !important; padding: 0 !important; display: block;"/>,
util.xmlToDom(<elem style="width: 1ex !important; position: absolute !important; padding: 0 !important; display: block;"/>, elem.ownerDocument).appendTo(elem);
elem.ownerDocument));
try { try {
return parseFloat(util.computedStyle(div).width); return parseFloat(div.style.width);
} }
finally { finally {
div.parentNode.removeChild(div); div.remove();
} }
}, },
@@ -1443,7 +1441,7 @@ var Buffer = Module("buffer", {
let arg = args[0]; let arg = args[0];
// FIXME: arg handling is a bit of a mess, check for filename // FIXME: arg handling is a bit of a mess, check for filename
dactyl.assert(!arg || arg[0] == ">" && !util.OS.isWindows, dactyl.assert(!arg || arg[0] == ">" && !config.OS.isWindows,
_("error.trailingCharacters")); _("error.trailingCharacters"));
const PRINTER = "PostScript/default"; const PRINTER = "PostScript/default";
@@ -1913,18 +1911,20 @@ var Buffer = Module("buffer", {
let frames = buffer.allFrames(null, true); let frames = buffer.allFrames(null, true);
let elements = array.flatten(frames.map(function (win) [m for (m in util.evaluateXPath(xpath, win.document))])) let elements = array.flatten(frames.map(function (win) [m for (m in DOM.XPath(xpath, win.document))]))
.filter(function (elem) { .filter(function (elem) {
if (isinstance(elem, [HTMLFrameElement, HTMLIFrameElement])) if (isinstance(elem, [HTMLFrameElement, HTMLIFrameElement]))
return Editor.getEditor(elem.contentWindow); return Editor.getEditor(elem.contentWindow);
if (elem.readOnly || elem instanceof HTMLInputElement && !Set.has(util.editableInputs, elem.type)) elem = DOM(elem);
if (elem[0].readOnly || !DOM(elem).isEditable)
return false; return false;
let computedStyle = util.computedStyle(elem); let style = elem.style;
let rect = elem.getBoundingClientRect(); let rect = elem.rect;
return computedStyle.visibility != "hidden" && computedStyle.display != "none" && return elem.isVisible &&
(elem instanceof Ci.nsIDOMXULTextBoxElement || computedStyle.MozUserFocus != "ignore") && (elem[0] instanceof Ci.nsIDOMXULTextBoxElement || style.MozUserFocus != "ignore") &&
rect.width && rect.height; rect.width && rect.height;
}); });
@@ -1932,7 +1932,7 @@ var Buffer = Module("buffer", {
elem = elements[Math.constrain(args.count, 1, elements.length) - 1]; elem = elements[Math.constrain(args.count, 1, elements.length) - 1];
} }
buffer.focusElement(elem); buffer.focusElement(elem);
util.scrollIntoView(elem); DOM(elem).scrollIntoView();
}, },
{ count: true }); { count: true });
@@ -2086,10 +2086,10 @@ var Buffer = Module("buffer", {
keepQuotes: true, keepQuotes: true,
setter: function (vals) { setter: function (vals) {
for (let [k, v] in Iterator(vals)) for (let [k, v] in Iterator(vals))
vals[k] = update(new String(v), { matcher: util.compileMatcher(Option.splitList(v)) }); vals[k] = update(new String(v), { matcher: DOM.compileMatcher(Option.splitList(v)) });
return vals; return vals;
}, },
validator: function (value) util.validateMatcher.call(this, value) validator: function (value) DOM.validateMatcher.call(this, value)
&& Object.keys(value).every(function (v) v.length == 1) && Object.keys(value).every(function (v) v.length == 1)
}); });

View File

@@ -279,7 +279,7 @@ var CommandWidgets = Class("CommandWidgets", {
// some host apps use "hostPrefixContext-copy" ids // some host apps use "hostPrefixContext-copy" ids
let xpath = "//xul:menuitem[contains(@id, '" + "ontext-" + tail + "') and not(starts-with(@id, 'dactyl-'))]"; let xpath = "//xul:menuitem[contains(@id, '" + "ontext-" + tail + "') and not(starts-with(@id, 'dactyl-'))]";
document.getElementById("dactyl-context-" + tail).style.listStyleImage = document.getElementById("dactyl-context-" + tail).style.listStyleImage =
util.computedStyle(util.evaluateXPath(xpath, document).snapshotItem(0)).listStyleImage; DOM(DOM.XPath(xpath, document).snapshotItem(0)).style.listStyleImage;
}); });
return document.getElementById("dactyl-contextmenu"); return document.getElementById("dactyl-contextmenu");
}), }),
@@ -899,7 +899,7 @@ var CommandLine = Module("commandline", {
this.savingOutput = true; this.savingOutput = true;
dactyl.trapErrors.apply(dactyl, [fn, self].concat(Array.slice(arguments, 2))); dactyl.trapErrors.apply(dactyl, [fn, self].concat(Array.slice(arguments, 2)));
this.savingOutput = false; this.savingOutput = false;
return output.map(function (elem) elem instanceof Node ? util.domToString(elem) : elem) return output.map(function (elem) elem instanceof Node ? DOM.stringify(elem) : elem)
.join("\n"); .join("\n");
} }
}, { }, {
@@ -1641,8 +1641,10 @@ var ItemList = Class("ItemList", {
_init: function _init() { _init: function _init() {
this._div = this._dom( this._div = this._dom(
<div class="ex-command-output" highlight="Normal" style="white-space: nowrap"> <div class="ex-command-output" highlight="Normal" style="white-space: nowrap">
<div highlight="Completions" key="noCompletions"><span highlight="Title">{_("completion.noCompletions")}</span></div> <div key="wrapper">
<div key="completions"/> <div highlight="Completions" key="noCompletions"><span highlight="Title">{_("completion.noCompletions")}</span></div>
<div key="completions"/>
</div>
<div highlight="Completions"> <div highlight="Completions">
{ {
template.map(util.range(0, options["maxitems"] * 2), function (i) template.map(util.range(0, options["maxitems"] * 2), function (i)
@@ -1653,7 +1655,7 @@ var ItemList = Class("ItemList", {
</div> </div>
</div>, this._divNodes); </div>, this._divNodes);
this._doc.body.replaceChild(this._div, this._doc.body.firstChild); this._doc.body.replaceChild(this._div, this._doc.body.firstChild);
util.scrollIntoView(this._div, true); DOM(this._divNodes.wrapper).scrollIntoView(true);
this._items.contextList.forEach(function init_eachContext(context) { this._items.contextList.forEach(function init_eachContext(context) {
delete context.cache.nodes; delete context.cache.nodes;
@@ -1758,7 +1760,7 @@ var ItemList = Class("ItemList", {
this._divNodes.noCompletions.style.display = haveCompletions ? "none" : "block"; this._divNodes.noCompletions.style.display = haveCompletions ? "none" : "block";
this._completionElements = util.evaluateXPath("//xhtml:div[@dactyl:highlight='CompItem']", this._doc); this._completionElements = DOM.XPath("//xhtml:div[@dactyl:highlight='CompItem']", this._doc);
return true; return true;
}, },
@@ -1828,7 +1830,7 @@ var ItemList = Class("ItemList", {
if (index >= 0) { if (index >= 0) {
this._getCompletion(index).setAttribute("selected", "true"); this._getCompletion(index).setAttribute("selected", "true");
if (this._container.height != 0) if (this._container.height != 0)
util.scrollIntoView(this._getCompletion(index)); DOM(this._getCompletion(index)).scrollIntoView();
} }
//if (index == 0) //if (index == 0)

View File

@@ -698,7 +698,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
}; };
// Find the tags in the document. // Find the tags in the document.
let addTags = function addTags(file, doc) { let addTags = function addTags(file, doc) {
for (let elem in util.evaluateXPath("//@tag|//dactyl:tags/text()|//dactyl:tag/text()", doc)) for (let elem in DOM.XPath("//@tag|//dactyl:tags/text()|//dactyl:tag/text()", doc))
for (let tag in values((elem.value || elem.textContent).split(/\s+/))) for (let tag in values((elem.value || elem.textContent).split(/\s+/)))
tagMap[tag] = file; tagMap[tag] = file;
}; };
@@ -716,7 +716,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
tagMap["all"] = tagMap["all.xml"] = "all"; tagMap["all"] = tagMap["all.xml"] = "all";
tagMap["versions"] = tagMap["versions.xml"] = "versions"; tagMap["versions"] = tagMap["versions.xml"] = "versions";
let files = findHelpFile("all").map(function (doc) let files = findHelpFile("all").map(function (doc)
[f.value for (f in util.evaluateXPath("//dactyl:include/@href", doc))]); [f.value for (f in DOM.XPath("//dactyl:include/@href", doc))]);
// Scrape the tags from the rest of the help files. // Scrape the tags from the rest of the help files.
array.flatten(files).forEach(function (file) { array.flatten(files).forEach(function (file) {
@@ -1255,10 +1255,11 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
* Opens one or more URLs. Returns true when load was initiated, or * Opens one or more URLs. Returns true when load was initiated, or
* false on error. * false on error.
* *
* @param {string|Array} urls A representation of the URLs to open. May be * @param {string|object|Array} urls A representation of the URLs to open. May be
* either a string, which will be passed to * either a string, which will be passed to
* {@see Dactyl#parseURLs}, or an array in the same format as * {@link Dactyl#parseURLs}, an array in the same format as
* would be returned by the same. * would be returned by the same, or an object as returned by
* {@link DOM#formData}.
* @param {object} params A set of parameters specifying how to open the * @param {object} params A set of parameters specifying how to open the
* URLs. The following properties are recognized: * URLs. The following properties are recognized:
* *
@@ -1312,21 +1313,23 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
return; return;
let browser = config.tabbrowser; let browser = config.tabbrowser;
function open(urls, where) { function open(loc, where) {
try { try {
let url = Array.concat(urls)[0]; if (isArray(loc))
let postdata = Array.concat(urls)[1]; loc = { url: loc[0], postData: loc[1] };
else if (isString(loc))
loc = { url: loc };
// decide where to load the first url // decide where to load the first url
switch (where) { switch (where) {
case dactyl.NEW_TAB: case dactyl.NEW_TAB:
if (!dactyl.has("tabs")) if (!dactyl.has("tabs"))
return open(urls, dactyl.NEW_WINDOW); return open(loc, dactyl.NEW_WINDOW);
return prefs.withContext(function () { return prefs.withContext(function () {
prefs.set("browser.tabs.loadInBackground", true); prefs.set("browser.tabs.loadInBackground", true);
return browser.loadOneTab(url, null, null, postdata, background).linkedBrowser.contentDocument; return browser.loadOneTab(loc.url, null, null, loc.postData, background).linkedBrowser.contentDocument;
}); });
case dactyl.NEW_WINDOW: case dactyl.NEW_WINDOW:
@@ -1335,7 +1338,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
browser = win.dactyl && win.dactyl.modules.config.tabbrowser || win.getBrowser(); browser = win.dactyl && win.dactyl.modules.config.tabbrowser || win.getBrowser();
// FALLTHROUGH // FALLTHROUGH
case dactyl.CURRENT_TAB: case dactyl.CURRENT_TAB:
browser.loadURIWithFlags(url, flags, null, null, postdata); browser.loadURIWithFlags(loc.url, flags, null, null, loc.postData);
return browser.contentWindow; return browser.contentWindow;
} }
} }
@@ -1380,7 +1383,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
return urls.map(function (url) { return urls.map(function (url) {
url = url.trim(); url = url.trim();
if (/^(\.{0,2}|~)(\/|$)/.test(url) || util.OS.isWindows && /^[a-z]:/i.test(url)) { if (/^(\.{0,2}|~)(\/|$)/.test(url) || config.OS.isWindows && /^[a-z]:/i.test(url)) {
try { try {
// Try to find a matching file. // Try to find a matching file.
let file = io.File(url); let file = io.File(url);
@@ -1945,7 +1948,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
function () { dactyl.restart(); }, function () { dactyl.restart(); },
{ argCount: "0" }); { argCount: "0" });
function findToolbar(name) util.evaluateXPath( function findToolbar(name) DOM.XPath(
"//*[@toolbarname=" + util.escapeString(name, "'") + " or " + "//*[@toolbarname=" + util.escapeString(name, "'") + " or " +
"@toolbarname=" + util.escapeString(name.trim(), "'") + "]", "@toolbarname=" + util.escapeString(name.trim(), "'") + "]",
document).snapshotItem(0); document).snapshotItem(0);
@@ -2136,7 +2139,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
completion.toolbar = function toolbar(context) { completion.toolbar = function toolbar(context) {
context.title = ["Toolbar"]; context.title = ["Toolbar"];
context.keys = { text: function (item) item.getAttribute("toolbarname"), description: function () "" }; context.keys = { text: function (item) item.getAttribute("toolbarname"), description: function () "" };
context.completions = util.evaluateXPath("//*[@toolbarname]", document); context.completions = DOM.XPath("//*[@toolbarname]", document);
}; };
completion.window = function window(context) { completion.window = function window(context) {

View File

@@ -209,7 +209,7 @@ var Editor = Module("editor", {
var editor_ = window.GetCurrentEditor ? GetCurrentEditor() var editor_ = window.GetCurrentEditor ? GetCurrentEditor()
: Editor.getEditor(document.commandDispatcher.focusedWindow); : Editor.getEditor(document.commandDispatcher.focusedWindow);
dactyl.assert(editor_); dactyl.assert(editor_);
text = Array.map(editor_.rootElement.childNodes, function (e) util.domToString(e, true)).join(""); text = Array.map(editor_.rootElement.childNodes, function (e) DOM.stringify(e, true)).join("");
} }
let origGroup = textBox && textBox.getAttributeNS(NS, "highlight") || ""; let origGroup = textBox && textBox.getAttributeNS(NS, "highlight") || "";
@@ -348,16 +348,7 @@ var Editor = Module("editor", {
elem = dactyl.focusedElement || document.commandDispatcher.focusedWindow; elem = dactyl.focusedElement || document.commandDispatcher.focusedWindow;
dactyl.assert(elem); dactyl.assert(elem);
try { return DOM(elem).editor;
if (elem instanceof Element)
return elem.QueryInterface(Ci.nsIDOMNSEditableElement).editor;
return elem.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIEditingSession)
.getEditorForWindow(elem);
}
catch (e) {
return null;
}
}, },
getController: function (cmd) { getController: function (cmd) {
@@ -582,7 +573,7 @@ var Editor = Module("editor", {
addMotionMap("d", "Delete motion", true, function (editor) { editor.cut(); }); addMotionMap("d", "Delete motion", true, function (editor) { editor.cut(); });
addMotionMap("c", "Change motion", true, function (editor) { editor.cut(); }, modes.INSERT); addMotionMap("c", "Change motion", true, function (editor) { editor.cut(); }, modes.INSERT);
addMotionMap("y", "Yank motion", false, function (editor, range) { dactyl.clipboardWrite(util.domToString(range)) }); addMotionMap("y", "Yank motion", false, function (editor, range) { dactyl.clipboardWrite(DOM.stringify(range)) });
let bind = function bind(names, description, action, params) let bind = function bind(names, description, action, params)
mappings.add([modes.INPUT], names, description, mappings.add([modes.INPUT], names, description,

View File

@@ -495,12 +495,6 @@ var Events = Module("events", {
this._activeMenubar = false; this._activeMenubar = false;
this.listen(window, this, "events"); this.listen(window, this, "events");
util.windows = [window].concat(util.windows);
},
destroy: function destroy() {
util.windows = util.windows.filter(function (w) w != window);
}, },
signals: { signals: {
@@ -922,14 +916,14 @@ var Events = Module("events", {
// https://bugzilla.mozilla.org/show_bug.cgi?id=432951 // https://bugzilla.mozilla.org/show_bug.cgi?id=432951
// --- // ---
// //
// The following fixes are only activated if util.OS.isMacOSX. // The following fixes are only activated if config.OS.isMacOSX.
// Technically, they prevent mappings from <C-Esc> (and // Technically, they prevent mappings from <C-Esc> (and
// <C-C-]> if your fancy keyboard permits such things<?>), but // <C-C-]> if your fancy keyboard permits such things<?>), but
// these <C-control> mappings are probably pathological (<C-Esc> // these <C-control> mappings are probably pathological (<C-Esc>
// certainly is on Windows), and so it is probably // certainly is on Windows), and so it is probably
// harmless to remove the util.OS.isMacOSX if desired. // harmless to remove the config.OS.isMacOSX if desired.
// //
else if (util.OS.isMacOSX && event.ctrlKey && charCode >= 27 && charCode <= 31) { else if (config.OS.isMacOSX && event.ctrlKey && charCode >= 27 && charCode <= 31) {
if (charCode == 27) { // [Ctrl-Bug 1/5] the <C-[> bug if (charCode == 27) { // [Ctrl-Bug 1/5] the <C-[> bug
key = "Esc"; key = "Esc";
modifier = modifier.replace("C-", ""); modifier = modifier.replace("C-", "");
@@ -1019,7 +1013,7 @@ var Events = Module("events", {
["key", key.toLowerCase()]); ["key", key.toLowerCase()]);
} }
let accel = util.OS.isMacOSX ? "metaKey" : "ctrlKey"; let accel = config.OS.isMacOSX ? "metaKey" : "ctrlKey";
let access = iter({ 1: "shiftKey", 2: "ctrlKey", 4: "altKey", 8: "metaKey" }) let access = iter({ 1: "shiftKey", 2: "ctrlKey", 4: "altKey", 8: "metaKey" })
.filter(function ([k, v]) this & k, prefs.get("ui.key.chromeAccess")) .filter(function ([k, v]) this & k, prefs.get("ui.key.chromeAccess"))
@@ -1160,7 +1154,7 @@ var Events = Module("events", {
let elem = event.originalTarget; let elem = event.originalTarget;
if (elem == window) if (elem == window)
util.windows = [window].concat(util.windows.filter(function (w) w != window)); overlay.activeWindow = window;
elem.dactylHadFocus = true; elem.dactylHadFocus = true;
if (event.target instanceof Ci.nsIDOMXULTextBoxElement) if (event.target instanceof Ci.nsIDOMXULTextBoxElement)
@@ -1444,7 +1438,7 @@ var Events = Module("events", {
let haveInput = modes.stack.some(function (m) m.main.input); let haveInput = modes.stack.some(function (m) m.main.input);
if (elem instanceof HTMLTextAreaElement if (elem instanceof HTMLTextAreaElement
|| elem instanceof Element && util.computedStyle(elem).MozUserModify === "read-write" || elem instanceof Element && DOM(elem).style.MozUserModify === "read-write"
|| elem == null && win && Editor.getEditor(win)) { || elem == null && win && Editor.getEditor(win)) {
if (modes.main == modes.VISUAL && elem.selectionEnd == elem.selectionStart) if (modes.main == modes.VISUAL && elem.selectionEnd == elem.selectionStart)
@@ -1525,7 +1519,7 @@ var Events = Module("events", {
key === "<Esc>" || key === "<C-[>", key === "<Esc>" || key === "<C-[>",
isHidden: function isHidden(elem, aggressive) { isHidden: function isHidden(elem, aggressive) {
if (util.computedStyle(elem).visibility !== "visible") if (DOM(elem).style.visibility !== "visible")
return true; return true;
if (aggressive) if (aggressive)
@@ -1539,12 +1533,9 @@ var Events = Module("events", {
}, },
isInputElement: function isInputElement(elem) { isInputElement: function isInputElement(elem) {
return elem instanceof HTMLInputElement && Set.has(util.editableInputs, elem.type) || return DOM(elem).isEditable ||
isinstance(elem, [HTMLEmbedElement, isinstance(elem, [HTMLEmbedElement, HTMLObjectElement,
HTMLObjectElement, HTMLSelectElement, HTMLSelectElement])
HTMLTextAreaElement,
Ci.nsIDOMXULTextBoxElement]) ||
elem instanceof Window && Editor.getEditor(elem);
}, },
kill: function kill(event) { kill: function kill(event) {

View File

@@ -255,7 +255,7 @@ var HintSession = Class("HintSession", CommandMode, {
getContainerOffsets: function _getContainerOffsets(doc) { getContainerOffsets: function _getContainerOffsets(doc) {
let body = doc.body || doc.documentElement; let body = doc.body || doc.documentElement;
// TODO: getComputedStyle returns null for Facebook channel_iframe doc - probable Gecko bug. // TODO: getComputedStyle returns null for Facebook channel_iframe doc - probable Gecko bug.
let style = util.computedStyle(body); let style = DOM(body).style;
if (style && /^(absolute|fixed|relative)$/.test(style.position)) { if (style && /^(absolute|fixed|relative)$/.test(style.position)) {
let rect = body.getClientRects()[0]; let rect = body.getClientRects()[0];
@@ -298,7 +298,7 @@ var HintSession = Class("HintSession", CommandMode, {
return false; return false;
if (!rect.width || !rect.height) if (!rect.width || !rect.height)
if (!Array.some(elem.childNodes, function (elem) elem instanceof Element && util.computedStyle(elem).float != "none" && isVisible(elem))) if (!Array.some(elem.childNodes, function (elem) elem instanceof Element && DOM(elem).style.float != "none" && isVisible(elem)))
return false; return false;
let computedStyle = doc.defaultView.getComputedStyle(elem, null); let computedStyle = doc.defaultView.getComputedStyle(elem, null);
@@ -309,12 +309,11 @@ var HintSession = Class("HintSession", CommandMode, {
let body = doc.body || doc.querySelector("body"); let body = doc.body || doc.querySelector("body");
if (body) { if (body) {
let fragment = util.xmlToDom(<div highlight="hints"/>, doc); let fragment = DOM(<div highlight="hints"/>, doc).appendTo(body);
body.appendChild(fragment); fragment.style.height; // Force application of binding.
util.computedStyle(fragment).height; // Force application of binding. let container = doc.getAnonymousElementByAttribute(fragment[0], "anonid", "hints") || fragment[0];
let container = doc.getAnonymousElementByAttribute(fragment, "anonid", "hints") || fragment;
let baseNodeAbsolute = util.xmlToDom(<span highlight="Hint" style="display: none;"/>, doc); let baseNode = DOM(<span highlight="Hint" style="display: none;"/>, doc)[0];
let mode = this.hintMode; let mode = this.hintMode;
let res = mode.matcher(doc); let res = mode.matcher(doc);
@@ -342,7 +341,7 @@ var HintSession = Class("HintSession", CommandMode, {
else else
hint.text = elem.textContent.toLowerCase(); hint.text = elem.textContent.toLowerCase();
hint.span = baseNodeAbsolute.cloneNode(false); hint.span = baseNode.cloneNode(false);
let leftPos = Math.max((rect.left + offsetX), offsetX); let leftPos = Math.max((rect.left + offsetX), offsetX);
let topPos = Math.max((rect.top + offsetY), offsetY); let topPos = Math.max((rect.top + offsetY), offsetY);
@@ -532,7 +531,7 @@ var HintSession = Class("HintSession", CommandMode, {
// Goddamn stupid fucking Gecko 1.x security manager bullshit. // Goddamn stupid fucking Gecko 1.x security manager bullshit.
try { delete doc.dactylLabels; } catch (e) { doc.dactylLabels = undefined; } try { delete doc.dactylLabels; } catch (e) { doc.dactylLabels = undefined; }
for (let elem in util.evaluateXPath("//*[@dactyl:highlight='hints']", doc)) for (let elem in DOM.XPath("//*[@dactyl:highlight='hints']", doc))
elem.parentNode.removeChild(elem); elem.parentNode.removeChild(elem);
for (let i in util.range(start, end + 1)) { for (let i in util.range(start, end + 1)) {
this.pageHints[i].ambiguous = false; this.pageHints[i].ambiguous = false;
@@ -824,7 +823,7 @@ var Hints = Module("hints", {
let type = elem.type; let type = elem.type;
if (elem instanceof HTMLInputElement && Set.has(util.editableInputs, elem.type)) if (DOM(elem).isInput)
return [elem.value, false]; return [elem.value, false];
else { else {
for (let [, option] in Iterator(options["hintinputs"])) { for (let [, option] in Iterator(options["hintinputs"])) {
@@ -1080,7 +1079,7 @@ var Hints = Module("hints", {
isVisible: function isVisible(elem, offScreen) { isVisible: function isVisible(elem, offScreen) {
let rect = elem.getBoundingClientRect(); let rect = elem.getBoundingClientRect();
if (!rect.width || !rect.height) if (!rect.width || !rect.height)
if (!Array.some(elem.childNodes, function (elem) elem instanceof Element && util.computedStyle(elem).float != "none" && isVisible(elem))) if (!Array.some(elem.childNodes, function (elem) elem instanceof Element && DOM(elem).style.float != "none" && isVisible(elem)))
return false; return false;
let win = elem.ownerDocument.defaultView; let win = elem.ownerDocument.defaultView;
@@ -1089,8 +1088,7 @@ var Hints = Module("hints", {
rect.right + win.scrollX > win.scrolMaxX + win.innerWidth)) rect.right + win.scrollX > win.scrolMaxX + win.innerWidth))
return false; return false;
let computedStyle = util.computedStyle(elem, null); if (!DOM(elem).isVisible)
if (computedStyle.visibility != "visible" || computedStyle.display == "none")
return false; return false;
return true; return true;
}, },
@@ -1249,8 +1247,6 @@ var Hints = Module("hints", {
function ({ self }) { self.escapeNumbers = !self.escapeNumbers; }); function ({ self }) { self.escapeNumbers = !self.escapeNumbers; });
}, },
options: function () { options: function () {
function xpath(arg) util.makeXPath(arg);
options.add(["extendedhinttags", "eht"], options.add(["extendedhinttags", "eht"],
"XPath or CSS selector strings of hintable elements for extended hint modes", "XPath or CSS selector strings of hintable elements for extended hint modes",
"regexpmap", { "regexpmap", {
@@ -1267,10 +1263,10 @@ var Hints = Module("hints", {
res ? res.matcher : default_, res ? res.matcher : default_,
setter: function (vals) { setter: function (vals) {
for (let value in values(vals)) for (let value in values(vals))
value.matcher = util.compileMatcher(Option.splitList(value.result)); value.matcher = DOM.compileMatcher(Option.splitList(value.result));
return vals; return vals;
}, },
validator: util.validateMatcher validator: DOM.validateMatcher
}); });
options.add(["hinttags", "ht"], options.add(["hinttags", "ht"],
@@ -1280,10 +1276,10 @@ var Hints = Module("hints", {
"[tabindex],[role=link],[role=button],[contenteditable=true]", "[tabindex],[role=link],[role=button],[contenteditable=true]",
{ {
setter: function (values) { setter: function (values) {
this.matcher = util.compileMatcher(values); this.matcher = DOM.compileMatcher(values);
return values; return values;
}, },
validator: util.validateMatcher validator: DOM.validateMatcher
}); });
options.add(["hintkeys", "hk"], options.add(["hintkeys", "hk"],

View File

@@ -42,7 +42,7 @@ var Marks = Module("marks", {
params.location = doc.documentURI, params.location = doc.documentURI,
params.offset = buffer.scrollPosition; params.offset = buffer.scrollPosition;
params.path = util.generateXPath(buffer.findScrollable(0, params.offset.x)); params.path = DOM(buffer.findScrollable(0, params.offset.x)).xpath;
params.timestamp = Date.now() * 1000; params.timestamp = Date.now() * 1000;
params.equals = function (m) this.location == m.location params.equals = function (m) this.location == m.location
&& this.offset.x == m.offset.x && this.offset.x == m.offset.x
@@ -227,11 +227,11 @@ var Marks = Module("marks", {
if (!mark.xpath) if (!mark.xpath)
var node = buffer.findScrollable(0, (mark.offset || mark.position).x) var node = buffer.findScrollable(0, (mark.offset || mark.position).x)
else else
for (node in util.evaluateXPath(mark.xpath, buffer.focusedFrame.document)) for (node in DOM.XPath(mark.xpath, buffer.focusedFrame.document))
break; break;
util.assert(node); util.assert(node);
util.scrollIntoView(node); DOM(node).scrollIntoView();
if (mark.offset) if (mark.offset)
Buffer.scrollToPosition(node, mark.offset.x, mark.offset.y); Buffer.scrollToPosition(node, mark.offset.x, mark.offset.y);

View File

@@ -24,7 +24,7 @@ var MOW = Module("mow", {
if (options["more"] && this.isScrollable(1)) { if (options["more"] && this.isScrollable(1)) {
// start the last executed command's output at the top of the screen // start the last executed command's output at the top of the screen
let elements = this.document.getElementsByClassName("ex-command-output"); let elements = this.document.getElementsByClassName("ex-command-output");
elements[elements.length - 1].scrollIntoView(true); DOM(elements[elements.length - 1]).scrollIntoView(true);
} }
else else
this.body.scrollTop = this.body.scrollHeight; this.body.scrollTop = this.body.scrollHeight;
@@ -37,7 +37,7 @@ var MOW = Module("mow", {
events.listen(window, this, "windowEvents"); events.listen(window, this, "windowEvents");
modules.mow = this; modules.mow = this;
let fontSize = util.computedStyle(document.documentElement).fontSize; let fontSize = DOM(document.documentElement).style.fontSize;
styles.system.add("font-size", "dactyl://content/buffer.xhtml", styles.system.add("font-size", "dactyl://content/buffer.xhtml",
"body { font-size: " + fontSize + "; } \ "body { font-size: " + fontSize + "; } \
html|html > xul|scrollbar { visibility: collapse !important; }", html|html > xul|scrollbar { visibility: collapse !important; }",
@@ -94,7 +94,7 @@ var MOW = Module("mow", {
* @param {string} highlightGroup * @param {string} highlightGroup
*/ */
echo: function echo(data, highlightGroup, silent) { echo: function echo(data, highlightGroup, silent) {
let body = this.document.body; let body = DOM(this.document.body);
this.widgets.message = null; this.widgets.message = null;
if (!commandline.commandVisible) if (!commandline.commandVisible)
@@ -122,11 +122,11 @@ var MOW = Module("mow", {
if (isObject(data) && !isinstance(data, _)) { if (isObject(data) && !isinstance(data, _)) {
this.lastOutput = null; this.lastOutput = null;
var output = util.xmlToDom(<div class="ex-command-output" style="white-space: nowrap" highlight={highlightGroup}/>, var output = DOM(<div class="ex-command-output" style="white-space: nowrap" highlight={highlightGroup}/>,
this.document); this.document);
data.document = this.document; data.document = this.document;
try { try {
output.appendChild(data.message); output.append(data.message);
} }
catch (e) { catch (e) {
util.reportError(e); util.reportError(e);
@@ -138,17 +138,17 @@ var MOW = Module("mow", {
let style = isString(data) ? "pre-wrap" : "nowrap"; let style = isString(data) ? "pre-wrap" : "nowrap";
this.lastOutput = <div class="ex-command-output" style={"white-space: " + style} highlight={highlightGroup}>{data}</div>; this.lastOutput = <div class="ex-command-output" style={"white-space: " + style} highlight={highlightGroup}>{data}</div>;
var output = util.xmlToDom(this.lastOutput, this.document); var output = DOM(this.lastOutput, this.document);
} }
// FIXME: need to make sure an open MOW is closed when commands // FIXME: need to make sure an open MOW is closed when commands
// that don't generate output are executed // that don't generate output are executed
if (!this.visible) { if (!this.visible) {
this.body.scrollTop = 0; this.body.scrollTop = 0;
body.textContent = ""; body.empty();
} }
body.appendChild(output); body.append(output);
let str = typeof data !== "xml" && data.message || data; let str = typeof data !== "xml" && data.message || data;
if (!silent) if (!silent)

View File

@@ -42,7 +42,7 @@ var StatusLine = Module("statusline", {
color: inherit !important; color: inherit !important;
} }
AddonButton:not(:hover) background: transparent; AddonButton:not(:hover) background: transparent;
]]>)({ padding: util.OS.isMacOSX ? "padding-right: 10px !important;" : "" })); ]]>)({ padding: config.OS.isMacOSX ? "padding-right: 10px !important;" : "" }));
if (document.getElementById("appmenu-button")) if (document.getElementById("appmenu-button"))
highlight.loadCSS(<![CDATA[ highlight.loadCSS(<![CDATA[

View File

@@ -37,7 +37,7 @@ var Tabs = Module("tabs", {
this.tabBinding = styles.system.add("tab-binding", "chrome://browser/content/browser.xul", String.replace(<><![CDATA[ this.tabBinding = styles.system.add("tab-binding", "chrome://browser/content/browser.xul", String.replace(<><![CDATA[
xul|tab { -moz-binding: url(chrome://dactyl/content/bindings.xml#tab) !important; } xul|tab { -moz-binding: url(chrome://dactyl/content/bindings.xml#tab) !important; }
]]></>, /tab-./g, function (m) util.OS.isMacOSX ? "tab-mac" : m), ]]></>, /tab-./g, function (m) config.OS.isMacOSX ? "tab-mac" : m),
false, true); false, true);
this.timeout(function () { this.timeout(function () {
@@ -75,14 +75,12 @@ var Tabs = Module("tabs", {
if (!node("dactyl-tab-number")) { if (!node("dactyl-tab-number")) {
let img = node("tab-icon-image"); let img = node("tab-icon-image");
if (img) { if (img) {
let nodes = {}; let dom = DOM(<xul xmlns:xul={XUL} xmlns:html={XHTML}
let dom = util.xmlToDom(<xul xmlns:xul={XUL} xmlns:html={XHTML}
><xul:hbox highlight="tab-number"><xul:label key="icon" align="center" highlight="TabIconNumber" class="dactyl-tab-icon-number"/></xul:hbox ><xul:hbox highlight="tab-number"><xul:label key="icon" align="center" highlight="TabIconNumber" class="dactyl-tab-icon-number"/></xul:hbox
><xul:hbox highlight="tab-number"><html:div key="label" highlight="TabNumber" class="dactyl-tab-number"/></xul:hbox ><xul:hbox highlight="tab-number"><html:div key="label" highlight="TabNumber" class="dactyl-tab-number"/></xul:hbox
></xul>.*, document, nodes); ></xul>.*, document).appendTo(img.parentNode);
img.parentNode.appendChild(dom); tab.__defineGetter__("dactylOrdinal", function () Number(dom.nodes.icon.value));
tab.__defineGetter__("dactylOrdinal", function () Number(nodes.icon.value)); tab.__defineSetter__("dactylOrdinal", function (i) dom.nodes.icon.value = dom.nodes.label.textContent = i);
tab.__defineSetter__("dactylOrdinal", function (i) nodes.icon.value = nodes.label.textContent = i);
} }
} }
} }

View File

@@ -111,7 +111,7 @@ var actions = {
name: "extr[ehash]", name: "extr[ehash]",
description: "Reload an extension", description: "Reload an extension",
action: function (addon) { action: function (addon) {
util.assert(util.haveGecko("2b"), _("command.notUseful", config.host)); util.assert(config.haveGecko("2b"), _("command.notUseful", config.host));
util.timeout(function () { util.timeout(function () {
addon.userDisabled = true; addon.userDisabled = true;
addon.userDisabled = false; addon.userDisabled = false;

View File

@@ -144,6 +144,7 @@ function defineModule(name, params, module) {
use[mod] = use[mod] || []; use[mod] = use[mod] || [];
use[mod].push(module); use[mod].push(module);
} }
module._lastModule = currentModule;
currentModule = module; currentModule = module;
module.startTime = Date.now(); module.startTime = Date.now();
} }
@@ -190,6 +191,7 @@ function endModule() {
require(mod, currentModule.NAME, "use"); require(mod, currentModule.NAME, "use");
loaded[currentModule.NAME] = 1; loaded[currentModule.NAME] = 1;
currentModule = currentModule._lastModule;
} }
function require(obj, name, from) { function require(obj, name, from) {
@@ -732,7 +734,7 @@ function Class() {
if (callable(args[0])) if (callable(args[0]))
superclass = args.shift(); superclass = args.shift();
if (loaded.util && util.haveGecko("6.0a1")) // Bug 657418. if (loaded.config && config.haveGecko("6.0a1")) // Bug 657418.
var Constructor = function Constructor() { var Constructor = function Constructor() {
var self = Object.create(Constructor.prototype, { var self = Object.create(Constructor.prototype, {
constructor: { value: Constructor }, constructor: { value: Constructor },

View File

@@ -23,7 +23,7 @@ var ConfigBase = Class("ConfigBase", {
*/ */
init: function init() { init: function init() {
this.features.push = deprecated("Set.add", function push(feature) Set.add(this, feature)); this.features.push = deprecated("Set.add", function push(feature) Set.add(this, feature));
if (util.haveGecko("2b")) if (this.haveGecko("2b"))
Set.add(this.features, "Gecko2"); Set.add(this.features, "Gecko2");
this.timeout(function () { this.timeout(function () {
@@ -40,7 +40,7 @@ var ConfigBase = Class("ConfigBase", {
highlight.loadCSS(this.CSS.replace(/__MSG_(.*?)__/g, function (m0, m1) _(m1))); highlight.loadCSS(this.CSS.replace(/__MSG_(.*?)__/g, function (m0, m1) _(m1)));
highlight.loadCSS(this.helpCSS.replace(/__MSG_(.*?)__/g, function (m0, m1) _(m1))); highlight.loadCSS(this.helpCSS.replace(/__MSG_(.*?)__/g, function (m0, m1) _(m1)));
if (!util.haveGecko("2b")) if (!this.haveGecko("2b"))
highlight.loadCSS(<![CDATA[ highlight.loadCSS(<![CDATA[
!TabNumber font-weight: bold; margin: 0px; padding-right: .8ex; !TabNumber font-weight: bold; margin: 0px; padding-right: .8ex;
!TabIconNumber { !TabIconNumber {
@@ -60,12 +60,12 @@ var ConfigBase = Class("ConfigBase", {
let elem = services.appShell.hiddenDOMWindow.document.createElement("div"); let elem = services.appShell.hiddenDOMWindow.document.createElement("div");
elem.style.cssText = this.cssText; elem.style.cssText = this.cssText;
let style = util.computedStyle(elem);
let keys = iter(Styles.propertyIter(this.cssText)).map(function (p) p.name).toArray(); let keys = iter(Styles.propertyIter(this.cssText)).map(function (p) p.name).toArray();
let bg = keys.some(function (k) /^background/.test(k)); let bg = keys.some(function (k) /^background/.test(k));
let fg = keys.indexOf("color") >= 0; let fg = keys.indexOf("color") >= 0;
let style = DOM(elem).style;
prefs[bg ? "safeSet" : "safeReset"]("ui.textHighlightBackground", hex(style.backgroundColor)); prefs[bg ? "safeSet" : "safeReset"]("ui.textHighlightBackground", hex(style.backgroundColor));
prefs[fg ? "safeSet" : "safeReset"]("ui.textHighlightForeground", hex(style.color)); prefs[fg ? "safeSet" : "safeReset"]("ui.textHighlightForeground", hex(style.color));
}; };
@@ -148,6 +148,87 @@ var ConfigBase = Class("ConfigBase", {
.nth(function (l) Set.has(langs, l), 0); .nth(function (l) Set.has(langs, l), 0);
}, },
/**
* A list of all known registered chrome and resource packages.
*/
get chromePackages() {
// Horrible hack.
let res = {};
function process(manifest) {
for each (let line in manifest.split(/\n+/)) {
let match = /^\s*(content|skin|locale|resource)\s+([^\s#]+)\s/.exec(line);
if (match)
res[match[2]] = true;
}
}
function processJar(file) {
let jar = services.ZipReader(file);
if (jar) {
if (jar.hasEntry("chrome.manifest"))
process(File.readStream(jar.getInputStream("chrome.manifest")));
jar.close();
}
}
for each (let dir in ["UChrm", "AChrom"]) {
dir = File(services.directory.get(dir, Ci.nsIFile));
if (dir.exists() && dir.isDirectory())
for (let file in dir.iterDirectory())
if (/\.manifest$/.test(file.leafName))
process(file.read());
dir = File(dir.parent);
if (dir.exists() && dir.isDirectory())
for (let file in dir.iterDirectory())
if (/\.jar$/.test(file.leafName))
processJar(file);
dir = dir.child("extensions");
if (dir.exists() && dir.isDirectory())
for (let ext in dir.iterDirectory()) {
if (/\.xpi$/.test(ext.leafName))
processJar(ext);
else {
if (ext.isFile())
ext = File(ext.read().replace(/\n*$/, ""));
let mf = ext.child("chrome.manifest");
if (mf.exists())
process(mf.read());
}
}
}
return Object.keys(res).sort();
},
/**
* Returns true if the current Gecko runtime is of the given version
* or greater.
*
* @param {string} ver The required version.
* @returns {boolean}
*/
haveGecko: function (ver) services.versionCompare.compare(services.runtime.platformVersion, ver) >= 0,
/** Dactyl's notion of the current operating system platform. */
OS: memoize({
_arch: services.runtime.OS,
/**
* @property {string} The normalised name of the OS. This is one of
* "Windows", "Mac OS X" or "Unix".
*/
get name() this.isWindows ? "Windows" : this.isMacOSX ? "Mac OS X" : "Unix",
/** @property {boolean} True if the OS is Windows. */
get isWindows() this._arch == "WINNT",
/** @property {boolean} True if the OS is Mac OS X. */
get isMacOSX() this._arch == "Darwin",
/** @property {boolean} True if the OS is some other *nix variant. */
get isUnix() !this.isWindows && !this.isMacOSX,
/** @property {RegExp} A RegExp which matches illegal characters in path components. */
get illegalCharacters() this.isWindows ? /[<>:"/\\|?*\x00-\x1f]/g : /\//g,
get pathListSep() this.isWindows ? ";" : ":"
}),
/** /**
* @property {string} The pathname of the VCS repository clone's root * @property {string} The pathname of the VCS repository clone's root
* directory if the application is running from one via an extension * directory if the application is running from one via an extension

View File

@@ -403,8 +403,8 @@ var RangeFind = Class("RangeFind", {
focus: function focus() { focus: function focus() {
if (this.lastRange) if (this.lastRange)
var node = util.evaluateXPath(RangeFind.selectNodePath, var node = DOM.XPath(RangeFind.selectNodePath,
this.lastRange.commonAncestorContainer).snapshotItem(0); this.lastRange.commonAncestorContainer).snapshotItem(0);
if (node) { if (node) {
node.focus(); node.focus();
// Re-highlight collapsed selection // Re-highlight collapsed selection
@@ -517,7 +517,7 @@ var RangeFind = Class("RangeFind", {
for (let frame in array.iterValues(win.frames)) { for (let frame in array.iterValues(win.frames)) {
let range = doc.createRange(); let range = doc.createRange();
if (util.computedStyle(frame.frameElement).visibility == "visible") { if (DOM(frame.frameElement).style.visibility == "visible") {
range.selectNode(frame.frameElement); range.selectNode(frame.frameElement);
pushRange(pageStart, RangeFind.endpoint(range, true)); pushRange(pageStart, RangeFind.endpoint(range, true));
pageStart = RangeFind.endpoint(range, false); pageStart = RangeFind.endpoint(range, false);

View File

@@ -299,7 +299,7 @@ var IO = Module("io", {
let rcFile1 = dir.child("." + config.name + "rc"); let rcFile1 = dir.child("." + config.name + "rc");
let rcFile2 = dir.child("_" + config.name + "rc"); let rcFile2 = dir.child("_" + config.name + "rc");
if (util.OS.isWindows) if (config.OS.isWindows)
[rcFile1, rcFile2] = [rcFile2, rcFile1]; [rcFile1, rcFile2] = [rcFile2, rcFile1];
if (rcFile1.exists() && rcFile1.isFile()) if (rcFile1.exists() && rcFile1.isFile())
@@ -393,9 +393,9 @@ var IO = Module("io", {
if (bin instanceof File || File.isAbsolutePath(bin)) if (bin instanceof File || File.isAbsolutePath(bin))
return this.File(bin); return this.File(bin);
let dirs = services.environment.get("PATH").split(util.OS.isWindows ? ";" : ":"); let dirs = services.environment.get("PATH").split(config.OS.isWindows ? ";" : ":");
// Windows tries the CWD first TODO: desirable? // Windows tries the CWD first TODO: desirable?
if (util.OS.isWindows) if (config.OS.isWindows)
dirs = [io.cwd].concat(dirs); dirs = [io.cwd].concat(dirs);
for (let [, dir] in Iterator(dirs)) for (let [, dir] in Iterator(dirs))
@@ -408,7 +408,7 @@ var IO = Module("io", {
// TODO: couldn't we just palm this off to the start command? // TODO: couldn't we just palm this off to the start command?
// automatically try to add the executable path extensions on windows // automatically try to add the executable path extensions on windows
if (util.OS.isWindows) { if (config.OS.isWindows) {
let extensions = services.environment.get("PATHEXT").split(";"); let extensions = services.environment.get("PATHEXT").split(";");
for (let [, extension] in Iterator(extensions)) { for (let [, extension] in Iterator(extensions)) {
file = dir.child(bin + extension); file = dir.child(bin + extension);
@@ -478,7 +478,7 @@ var IO = Module("io", {
system: function (command, input, callback) { system: function (command, input, callback) {
util.dactyl.echomsg(_("io.callingShell", command), 4); util.dactyl.echomsg(_("io.callingShell", command), 4);
function escape(str) '"' + String.replace(str, /[\\"$]/g, "\\$&") + '"'; let { shellEscape } = util.closure;
return this.withTempFiles(function (stdin, stdout, cmd) { return this.withTempFiles(function (stdin, stdout, cmd) {
if (input instanceof File) if (input instanceof File)
@@ -505,17 +505,17 @@ var IO = Module("io", {
util.assert(shell, _("error.invalid", "'shell'")); util.assert(shell, _("error.invalid", "'shell'"));
if (isArray(command)) if (isArray(command))
command = command.map(escape).join(" "); command = command.map(shellEscape).join(" ");
// TODO: implement 'shellredir' // TODO: implement 'shellredir'
if (util.OS.isWindows && !/sh/.test(shell.leafName)) { if (config.OS.isWindows && !/sh/.test(shell.leafName)) {
command = "cd /D " + this.cwd.path + " && " + command + " > " + stdout.path + " 2>&1" + " < " + stdin.path; command = "cd /D " + this.cwd.path + " && " + command + " > " + stdout.path + " 2>&1" + " < " + stdin.path;
var res = this.run(shell, shcf.split(/\s+/).concat(command), callback ? async : true); var res = this.run(shell, shcf.split(/\s+/).concat(command), callback ? async : true);
} }
else { else {
cmd.write("cd " + escape(this.cwd.path) + "\n" + cmd.write("cd " + shellEscape(this.cwd.path) + "\n" +
["exec", ">" + escape(stdout.path), "2>&1", "<" + escape(stdin.path), ["exec", ">" + shellEscape(stdout.path), "2>&1", "<" + shellEscape(stdin.path),
escape(shell.path), shcf, escape(command)].join(" ")); shellEscape(shell.path), shcf, shellEscape(command)].join(" "));
res = this.run("/bin/sh", ["-e", cmd.path], callback ? async : true); res = this.run("/bin/sh", ["-e", cmd.path], callback ? async : true);
} }
@@ -556,7 +556,7 @@ var IO = Module("io", {
const rtpvar = config.idName + "_RUNTIME"; const rtpvar = config.idName + "_RUNTIME";
let rtp = services.environment.get(rtpvar); let rtp = services.environment.get(rtpvar);
if (!rtp) { if (!rtp) {
rtp = "~/" + (util.OS.isWindows ? "" : ".") + config.name; rtp = "~/" + (config.OS.isWindows ? "" : ".") + config.name;
services.environment.set(rtpvar, rtp); services.environment.set(rtpvar, rtp);
} }
return rtp; return rtp;
@@ -644,7 +644,7 @@ var IO = Module("io", {
commands.add(["mks[yntax]"], commands.add(["mks[yntax]"],
"Generate a Vim syntax file", "Generate a Vim syntax file",
function (args) { function (args) {
let runtime = util.OS.isWindows ? "~/vimfiles/" : "~/.vim/"; let runtime = config.OS.isWindows ? "~/vimfiles/" : "~/.vim/";
let file = io.File(runtime + "syntax/" + config.name + ".vim"); let file = io.File(runtime + "syntax/" + config.name + ".vim");
if (args.length) if (args.length)
file = io.File(args[0]); file = io.File(args[0]);
@@ -886,7 +886,7 @@ unlet s:cpo_save
completion.environment = function environment(context) { completion.environment = function environment(context) {
context.title = ["Environment Variable", "Value"]; context.title = ["Environment Variable", "Value"];
context.generate = function () context.generate = function ()
io.system(util.OS.isWindows ? "set" : "env") io.system(config.OS.isWindows ? "set" : "env")
.output.split("\n") .output.split("\n")
.filter(function (line) line.indexOf("=") > 0) .filter(function (line) line.indexOf("=") > 0)
.map(function (line) line.match(/([^=]+)=(.*)/).slice(1)); .map(function (line) line.match(/([^=]+)=(.*)/).slice(1));
@@ -956,7 +956,7 @@ unlet s:cpo_save
completion.shellCommand = function shellCommand(context) { completion.shellCommand = function shellCommand(context) {
context.title = ["Shell Command", "Path"]; context.title = ["Shell Command", "Path"];
context.generate = function () { context.generate = function () {
let dirNames = services.environment.get("PATH").split(util.OS.isWindows ? ";" : ":"); let dirNames = services.environment.get("PATH").split(config.OS.pathListSep);
let commands = []; let commands = [];
for (let [, dirName] in Iterator(dirNames)) { for (let [, dirName] in Iterator(dirNames)) {
@@ -987,7 +987,7 @@ unlet s:cpo_save
if (!match.path) { if (!match.path) {
context.key = match.proto; context.key = match.proto;
context.advance(match.proto.length); context.advance(match.proto.length);
context.generate = function () util.chromePackages.map(function (p) [p, match.proto + p + "/"]); context.generate = function () config.chromePackages.map(function (p) [p, match.proto + p + "/"]);
} }
else if (match.scheme === "chrome") { else if (match.scheme === "chrome") {
context.key = match.prefix; context.key = match.prefix;
@@ -1001,7 +1001,7 @@ unlet s:cpo_save
} }
if (!match || match.scheme === "resource" && match.path) if (!match || match.scheme === "resource" && match.path)
if (/^(\.{0,2}|~)\/|^file:/.test(context.filter) if (/^(\.{0,2}|~)\/|^file:/.test(context.filter)
|| util.OS.isWindows && /^[a-z]:/i.test(context.filter) || config.OS.isWindows && /^[a-z]:/i.test(context.filter)
|| util.getFile(context.filter) || util.getFile(context.filter)
|| io.isJarURL(context.filter)) || io.isJarURL(context.filter))
completion.file(context, full); completion.file(context, full);
@@ -1030,7 +1030,7 @@ unlet s:cpo_save
const { completion, options } = modules; const { completion, options } = modules;
var shell, shellcmdflag; var shell, shellcmdflag;
if (util.OS.isWindows) { if (config.OS.isWindows) {
shell = "cmd.exe"; shell = "cmd.exe";
shellcmdflag = "/c"; shellcmdflag = "/c";
} }
@@ -1077,7 +1077,7 @@ unlet s:cpo_save
"string", shellcmdflag, "string", shellcmdflag,
{ {
getter: function (value) { getter: function (value) {
if (this.hasChanged || !util.OS.isWindows) if (this.hasChanged || !config.OS.isWindows)
return value; return value;
return /sh/.test(options["shell"]) ? "-c" : "/c"; return /sh/.test(options["shell"]) ? "-c" : "/c";
} }

View File

@@ -8,7 +8,7 @@ try {
Components.utils.import("resource://dactyl/bootstrap.jsm"); Components.utils.import("resource://dactyl/bootstrap.jsm");
defineModule("overlay", { defineModule("overlay", {
exports: ["ModuleBase"], exports: ["ModuleBase", "overlay"],
require: ["config", "io", "services", "util"] require: ["config", "io", "services", "util"]
}, this); }, this);
@@ -28,11 +28,13 @@ var ModuleBase = Class("ModuleBase", {
var Overlay = Module("Overlay", { var Overlay = Module("Overlay", {
init: function init() { init: function init() {
let overlay = this;
services["dactyl:"]; // Hack. Force module initialization. services["dactyl:"]; // Hack. Force module initialization.
config.loadStyles(); config.loadStyles();
util.overlayWindow(config.overlayChrome, function overlay(window) ({ util.overlayWindow(config.overlayChrome, function _overlay(window) ({
init: function onInit(document) { init: function onInit(document) {
/** /**
* @constructor Module * @constructor Module
@@ -308,9 +310,15 @@ var Overlay = Module("Overlay", {
defineModule.loadLog.push("Loaded in " + (Date.now() - start) + "ms"); defineModule.loadLog.push("Loaded in " + (Date.now() - start) + "ms");
util.dump(overlay);
overlay.windows = array.uniq(overlay.windows.concat(window), true);
modules.events.listen(window, "unload", function onUnload() { modules.events.listen(window, "unload", function onUnload() {
window.removeEventListener("unload", onUnload.wrapped, false); window.removeEventListener("unload", onUnload.wrapped, false);
overlay.windows = overlay.windows.filter(function (w) w != window);
for each (let mod in modules.moduleList.reverse()) { for each (let mod in modules.moduleList.reverse()) {
mod.stale = true; mod.stale = true;
@@ -320,7 +328,19 @@ var Overlay = Module("Overlay", {
}, false); }, false);
} }
})); }));
} },
/**
* The most recently active dactyl window.
*/
get activeWindow() this.windows[0],
set activeWindow(win) this.windows = [win].concat(this.windows.filter(function (w) w != win)),
/**
* A list of extant dactyl windows.
*/
windows: Class.memoize(function () [])
}); });
endModule(); endModule();

View File

@@ -702,7 +702,7 @@ var Styles = Module("Styles", {
})); }));
}, },
completion: function (dactyl, modules, window) { completion: function (dactyl, modules, window) {
const names = Array.slice(util.computedStyle(window.document.createElement("div"))); const names = Array.slice(DOM(<div/>, window.document).style);
modules.completion.css = function (context) { modules.completion.css = function (context) {
context.title = ["CSS Property"]; context.title = ["CSS Property"];
context.keys = { text: function (p) p + ":", description: function () "" }; context.keys = { text: function (p) p + ":", description: function () "" };

File diff suppressed because it is too large Load Diff