mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-20 12:38:00 +01:00
Add experimental jQuery-ish DOM object.
This commit is contained in:
@@ -491,7 +491,7 @@ var Buffer = Module("buffer", {
|
|||||||
try {
|
try {
|
||||||
let [x, y] = elem.getAttribute("coords").split(",").map(parseFloat);
|
let [x, y] = elem.getAttribute("coords").split(",").map(parseFloat);
|
||||||
|
|
||||||
events.dispatch(elem, events.create(elem.ownerDocument, "mouseover", { screenX: x, screenY: y }));
|
DOM(elem).mouseover({ screenX: x, screenY: y });
|
||||||
}
|
}
|
||||||
catch (e) {}
|
catch (e) {}
|
||||||
}
|
}
|
||||||
@@ -606,13 +606,15 @@ var Buffer = Module("buffer", {
|
|||||||
|
|
||||||
prefs.withContext(function () {
|
prefs.withContext(function () {
|
||||||
prefs.set("browser.tabs.loadInBackground", true);
|
prefs.set("browser.tabs.loadInBackground", true);
|
||||||
["mousedown", "mouseup", "click"].slice(0, util.haveGecko("2b") ? 2 : 3)
|
let params = {
|
||||||
.forEach(function (event) {
|
screenX: offsetX, screenY: offsetY,
|
||||||
events.dispatch(elem, events.create(doc, event, {
|
ctrlKey: ctrlKey, shiftKey: shiftKey, metaKey: ctrlKey
|
||||||
screenX: offsetX, screenY: offsetY,
|
};
|
||||||
ctrlKey: ctrlKey, shiftKey: shiftKey, metaKey: ctrlKey
|
|
||||||
}));
|
DOM(elem).mousedown(params).mouseup(params);
|
||||||
});
|
if (!util.haveGecko("2b"))
|
||||||
|
DOM(elem).click(params);
|
||||||
|
|
||||||
let sel = util.selectionController(win);
|
let sel = util.selectionController(win);
|
||||||
sel.getSelection(sel.SELECTION_FOCUS_REGION).collapseToStart();
|
sel.getSelection(sel.SELECTION_FOCUS_REGION).collapseToStart();
|
||||||
});
|
});
|
||||||
@@ -1422,8 +1424,7 @@ var Buffer = Module("buffer", {
|
|||||||
let file = io.File(path);
|
let file = io.File(path);
|
||||||
dactyl.assert(file.exists());
|
dactyl.assert(file.exists());
|
||||||
|
|
||||||
elem.value = file.path;
|
DOM(elem).val(file.path).change();
|
||||||
events.dispatch(elem, events.create(elem.ownerDocument, "change", {}));
|
|
||||||
}
|
}
|
||||||
}).open(elem.value);
|
}).open(elem.value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ var Editor = Module("editor", {
|
|||||||
elem.scrollTop = top;
|
elem.scrollTop = top;
|
||||||
elem.scrollLeft = left;
|
elem.scrollLeft = left;
|
||||||
|
|
||||||
events.dispatch(elem, events.create(elem.ownerDocument, "input"));
|
DOM(elem).input();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -248,10 +248,10 @@ var Editor = Module("editor", {
|
|||||||
textBox.value = val;
|
textBox.value = val;
|
||||||
|
|
||||||
if (false) {
|
if (false) {
|
||||||
textBox.setAttributeNS(NS, "modifiable", true);
|
let elem = DOM(textBox);
|
||||||
util.computedStyle(textBox).MozUserInput;
|
elem.attrNS(NS, "modifiable", true)
|
||||||
events.dispatch(textBox, events.create(textBox.ownerDocument, "input", {}));
|
.style.MozUserInput;
|
||||||
textBox.removeAttributeNS(NS, "modifiable");
|
elem.input().attrNS(NS, "modifiable", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -641,8 +641,8 @@ var Events = Module("events", {
|
|||||||
let elem = target || event.originalTarget;
|
let elem = target || event.originalTarget;
|
||||||
if (elem) {
|
if (elem) {
|
||||||
let doc = elem.ownerDocument || elem.document || elem;
|
let doc = elem.ownerDocument || elem.document || elem;
|
||||||
let evt = events.create(doc, event.type, event);
|
let evt = DOM.Event(doc, event.type, event);
|
||||||
events.dispatch(elem, evt, extra);
|
DOM.Event.dispatch(elem, evt, extra);
|
||||||
}
|
}
|
||||||
else if (i > 0 && event.type === "keypress")
|
else if (i > 0 && event.type === "keypress")
|
||||||
events.events.keypress.call(events, event);
|
events.events.keypress.call(events, event);
|
||||||
@@ -691,10 +691,10 @@ var Events = Module("events", {
|
|||||||
evt.isMacro = true;
|
evt.isMacro = true;
|
||||||
evt.dactylMode = mode;
|
evt.dactylMode = mode;
|
||||||
evt.dactylSavedEvents = savedEvents;
|
evt.dactylSavedEvents = savedEvents;
|
||||||
this.feedingEvent = evt;
|
DOM.Event.feedingEvent = evt;
|
||||||
|
|
||||||
let doc = document.commandDispatcher.focusedWindow.document;
|
let doc = document.commandDispatcher.focusedWindow.document;
|
||||||
let event = events.create(doc, type, evt);
|
|
||||||
let target = dactyl.focusedElement
|
let target = dactyl.focusedElement
|
||||||
|| ["complete", "interactive"].indexOf(doc.readyState) >= 0 && doc.documentElement
|
|| ["complete", "interactive"].indexOf(doc.readyState) >= 0 && doc.documentElement
|
||||||
|| doc.defaultView;
|
|| doc.defaultView;
|
||||||
@@ -703,6 +703,7 @@ var Events = Module("events", {
|
|||||||
["<Return>", "<Space>"].indexOf(key) == -1)
|
["<Return>", "<Space>"].indexOf(key) == -1)
|
||||||
target = target.ownerDocument.documentElement;
|
target = target.ownerDocument.documentElement;
|
||||||
|
|
||||||
|
let event = DOM.Event(doc, type, evt);
|
||||||
if (!evt_obj.dactylString && !mode)
|
if (!evt_obj.dactylString && !mode)
|
||||||
events.dispatch(target, event, evt);
|
events.dispatch(target, event, evt);
|
||||||
else if (type === "keypress")
|
else if (type === "keypress")
|
||||||
@@ -717,7 +718,7 @@ var Events = Module("events", {
|
|||||||
util.reportError(e);
|
util.reportError(e);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
this.feedingEvent = null;
|
DOM.Event.feedingEvent = null;
|
||||||
this.feedingKeys = wasFeeding;
|
this.feedingKeys = wasFeeding;
|
||||||
if (quiet)
|
if (quiet)
|
||||||
commandline.quiet = wasQuiet;
|
commandline.quiet = wasQuiet;
|
||||||
@@ -726,64 +727,8 @@ var Events = Module("events", {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
create: deprecated("DOM.Event", function create() DOM.Event.apply(null, arguments)),
|
||||||
* Creates an actual event from a pseudo-event object.
|
dispatch: deprecated("DOM.Event.dispatch", function dispatch() DOM.Event.dispatch.apply(DOM.Event, arguments)),
|
||||||
*
|
|
||||||
* The pseudo-event object (such as may be retrieved from events.fromString)
|
|
||||||
* should have any properties you want the event to have.
|
|
||||||
*
|
|
||||||
* @param {Document} doc The DOM document to associate this event with
|
|
||||||
* @param {Type} type The type of event (keypress, click, etc.)
|
|
||||||
* @param {Object} opts The pseudo-event. @optional
|
|
||||||
*/
|
|
||||||
create: function (doc, type, opts) {
|
|
||||||
const DEFAULTS = {
|
|
||||||
HTML: {
|
|
||||||
type: type, bubbles: true, cancelable: false
|
|
||||||
},
|
|
||||||
Key: {
|
|
||||||
type: type,
|
|
||||||
bubbles: true, cancelable: true,
|
|
||||||
view: doc.defaultView,
|
|
||||||
ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
|
|
||||||
keyCode: 0, charCode: 0
|
|
||||||
},
|
|
||||||
Mouse: {
|
|
||||||
type: type,
|
|
||||||
bubbles: true, cancelable: true,
|
|
||||||
view: doc.defaultView,
|
|
||||||
detail: 1,
|
|
||||||
screenX: 0, screenY: 0,
|
|
||||||
clientX: 0, clientY: 0,
|
|
||||||
ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
|
|
||||||
button: 0,
|
|
||||||
relatedTarget: null
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
opts = opts || {};
|
|
||||||
|
|
||||||
var t = this._create_types[type];
|
|
||||||
var evt = doc.createEvent((t || "HTML") + "Events");
|
|
||||||
|
|
||||||
let defaults = DEFAULTS[t || "HTML"];
|
|
||||||
|
|
||||||
let args = Object.keys(defaults)
|
|
||||||
.map(function (k) k in opts ? opts[k] : defaults[k]);
|
|
||||||
|
|
||||||
evt["init" + t + "Event"].apply(evt, args);
|
|
||||||
return evt;
|
|
||||||
},
|
|
||||||
|
|
||||||
_create_types: Class.memoize(function () iter(
|
|
||||||
{
|
|
||||||
Mouse: "click mousedown mouseout mouseover mouseup",
|
|
||||||
Key: "keydown keypress keyup",
|
|
||||||
"": "change dactyl-input input submit"
|
|
||||||
}
|
|
||||||
).map(function ([k, v]) v.split(" ").map(function (v) [v, k]))
|
|
||||||
.flatten()
|
|
||||||
.toObject()),
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a user-input string of keys into a canonical
|
* Converts a user-input string of keys into a canonical
|
||||||
@@ -817,44 +762,6 @@ var Events = Module("events", {
|
|||||||
yield match[0];
|
yield match[0];
|
||||||
}()),
|
}()),
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatches an event to an element as if it were a native event.
|
|
||||||
*
|
|
||||||
* @param {Node} target The DOM node to which to dispatch the event.
|
|
||||||
* @param {Event} event The event to dispatch.
|
|
||||||
*/
|
|
||||||
dispatch: Class.memoize(function ()
|
|
||||||
util.haveGecko("2b")
|
|
||||||
? function dispatch(target, event, extra) {
|
|
||||||
try {
|
|
||||||
this.feedingEvent = extra;
|
|
||||||
if (target instanceof Element)
|
|
||||||
// This causes a crash on Gecko<2.0, it seems.
|
|
||||||
return (target.ownerDocument || target.document || target).defaultView
|
|
||||||
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils)
|
|
||||||
.dispatchDOMEventViaPresShell(target, event, true);
|
|
||||||
else {
|
|
||||||
target.dispatchEvent(event);
|
|
||||||
return !event.getPreventDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
util.reportError(e);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
this.feedingEvent = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
: function dispatch(target, event, extra) {
|
|
||||||
try {
|
|
||||||
this.feedingEvent = extra;
|
|
||||||
target.dispatchEvent(update(event, extra));
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
this.feedingEvent = null;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
get defaultTarget() dactyl.focusedElement || content.document.body || document.documentElement,
|
get defaultTarget() dactyl.focusedElement || content.document.body || document.documentElement,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1306,11 +1213,11 @@ var Events = Module("events", {
|
|||||||
let duringFeed = this.duringFeed || [];
|
let duringFeed = this.duringFeed || [];
|
||||||
this.duringFeed = [];
|
this.duringFeed = [];
|
||||||
try {
|
try {
|
||||||
if (this.feedingEvent)
|
if (DOM.Event.feedingEvent)
|
||||||
for (let [k, v] in Iterator(this.feedingEvent))
|
for (let [k, v] in Iterator(DOM.Event.feedingEvent))
|
||||||
if (!(k in event))
|
if (!(k in event))
|
||||||
event[k] = v;
|
event[k] = v;
|
||||||
this.feedingEvent = null;
|
DOM.Event.feedingEvent = null;
|
||||||
|
|
||||||
let key = events.toString(event);
|
let key = events.toString(event);
|
||||||
|
|
||||||
@@ -1321,7 +1228,7 @@ var Events = Module("events", {
|
|||||||
elem.dactylKeyPress = elem.value;
|
elem.dactylKeyPress = elem.value;
|
||||||
util.timeout(function () {
|
util.timeout(function () {
|
||||||
if (elem.dactylKeyPress !== undefined && elem.value !== elem.dactylKeyPress)
|
if (elem.dactylKeyPress !== undefined && elem.value !== elem.dactylKeyPress)
|
||||||
events.dispatch(elem, events.create(elem.ownerDocument, "dactyl-input"));
|
DOM(elem).dactylInput();
|
||||||
elem.dactylKeyPress = undefined;
|
elem.dactylKeyPress = undefined;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1425,7 +1332,7 @@ var Events = Module("events", {
|
|||||||
this.keyEvents = [];
|
this.keyEvents = [];
|
||||||
|
|
||||||
let pass = this.passing && !event.isMacro ||
|
let pass = this.passing && !event.isMacro ||
|
||||||
this.feedingEvent && this.feedingEvent.isReplay ||
|
DOM.Event.feedingEvent && DOM.Event.feedingEvent.isReplay ||
|
||||||
event.isReplay ||
|
event.isReplay ||
|
||||||
modes.main == modes.PASS_THROUGH ||
|
modes.main == modes.PASS_THROUGH ||
|
||||||
modes.main == modes.QUOTE
|
modes.main == modes.QUOTE
|
||||||
|
|||||||
@@ -731,8 +731,10 @@ var Styles = Module("Styles", {
|
|||||||
template.highlightCSS = function highlightCSS(css) {
|
template.highlightCSS = function highlightCSS(css) {
|
||||||
XML.prettyPrinting = XML.ignoreWhitespace = false;
|
XML.prettyPrinting = XML.ignoreWhitespace = false;
|
||||||
|
|
||||||
return this.highlightRegexp(css, patterns.property, function (match) <>{
|
return this.highlightRegexp(css, patterns.property, function (match) {
|
||||||
match.preSpace}{template.filter(match.name)}: {
|
if (!match.length)
|
||||||
|
return <></>;
|
||||||
|
return <>{match.preSpace}{template.filter(match.name)}: {
|
||||||
|
|
||||||
template.highlightRegexp(match.value, patterns.token, function (match) {
|
template.highlightRegexp(match.value, patterns.token, function (match) {
|
||||||
if (match.function)
|
if (match.function)
|
||||||
@@ -749,7 +751,7 @@ var Styles = Module("Styles", {
|
|||||||
})
|
})
|
||||||
|
|
||||||
}{ match.postSpace }</>
|
}{ match.postSpace }</>
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ try {
|
|||||||
Components.utils.import("resource://dactyl/bootstrap.jsm");
|
Components.utils.import("resource://dactyl/bootstrap.jsm");
|
||||||
let frag=1;
|
let frag=1;
|
||||||
defineModule("util", {
|
defineModule("util", {
|
||||||
exports: ["frag", "FailedAssertion", "Math", "NS", "Point", "Util", "XBL", "XHTML", "XUL", "util"],
|
exports: ["$", "DOM", "FailedAssertion", "Math", "NS", "Point", "Util", "XBL", "XHTML", "XUL", "util"],
|
||||||
require: ["services"],
|
require: ["services"],
|
||||||
use: ["commands", "config", "highlight", "messages", "storage", "template"]
|
use: ["commands", "config", "highlight", "messages", "storage", "template"]
|
||||||
}, this);
|
}, this);
|
||||||
@@ -37,15 +37,16 @@ var FailedAssertion = Class("FailedAssertion", ErrorBase, {
|
|||||||
var Point = Struct("x", "y");
|
var Point = Struct("x", "y");
|
||||||
|
|
||||||
var wrapCallback = function wrapCallback(fn) {
|
var wrapCallback = function wrapCallback(fn) {
|
||||||
fn.wrapper = function wrappedCallback () {
|
if (!fn.wrapper)
|
||||||
try {
|
fn.wrapper = function wrappedCallback() {
|
||||||
return fn.apply(this, arguments);
|
try {
|
||||||
}
|
return fn.apply(this, arguments);
|
||||||
catch (e) {
|
}
|
||||||
util.reportError(e);
|
catch (e) {
|
||||||
return undefined;
|
util.reportError(e);
|
||||||
}
|
return undefined;
|
||||||
};
|
}
|
||||||
|
};
|
||||||
fn.wrapper.wrapped = fn;
|
fn.wrapper.wrapped = fn;
|
||||||
return fn.wrapper;
|
return fn.wrapper;
|
||||||
}
|
}
|
||||||
@@ -161,6 +162,14 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
|
|||||||
return condition;
|
return condition;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CamelCases a -non-camel-cased identifier name.
|
||||||
|
*
|
||||||
|
* @param {string} name The name to mangle.
|
||||||
|
* @returns {string} The mangled name.
|
||||||
|
*/
|
||||||
|
camelCase: function camelCase(name) String.replace(name, /-(.)/g, function (m, m1) m1.toUpperCase()),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Capitalizes the first character of the given string.
|
* Capitalizes the first character of the given string.
|
||||||
* @param {string} str The string to capitalize
|
* @param {string} str The string to capitalize
|
||||||
@@ -2127,6 +2136,552 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
|
|||||||
Array: array
|
Array: array
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var DOM = Class("DOM", {
|
||||||
|
init: function init(val, context) {
|
||||||
|
let self;
|
||||||
|
let length = 0;
|
||||||
|
|
||||||
|
if (context instanceof Ci.nsIDOMDocument)
|
||||||
|
this.document = context;
|
||||||
|
|
||||||
|
if (typeof val == "string")
|
||||||
|
val = context.querySelectorAll(val);
|
||||||
|
|
||||||
|
if (val == null)
|
||||||
|
;
|
||||||
|
else if (typeof val == "xml")
|
||||||
|
this[length++] = util.xmlToDom(val, context);
|
||||||
|
else if (val instanceof Ci.nsIDOMNode)
|
||||||
|
this[length++] = val;
|
||||||
|
else if ("length" in val)
|
||||||
|
for (let i = 0; i < val.length; i++)
|
||||||
|
this[length++] = val[i];
|
||||||
|
|
||||||
|
this.length = length;
|
||||||
|
return self || this;
|
||||||
|
},
|
||||||
|
|
||||||
|
__iterator__: function __iterator__() {
|
||||||
|
for (let i = 0; i < this.length; i++)
|
||||||
|
yield this[i];
|
||||||
|
},
|
||||||
|
|
||||||
|
Empty: function Empty() this.constructor(null, this.document),
|
||||||
|
|
||||||
|
get items() {
|
||||||
|
for (let i = 0; i < this.length; i++)
|
||||||
|
yield this.eq(i);
|
||||||
|
},
|
||||||
|
|
||||||
|
get document() this._document || this[0].ownerDocument,
|
||||||
|
set document(val) this._document = val,
|
||||||
|
|
||||||
|
attrHooks: array.toObject([
|
||||||
|
["", {
|
||||||
|
href: { get: function (elem) elem.href },
|
||||||
|
src: { get: function (elem) elem.src }
|
||||||
|
}]
|
||||||
|
]),
|
||||||
|
|
||||||
|
matcher: function matcher(sel) {
|
||||||
|
let res;
|
||||||
|
|
||||||
|
if (/^([a-z0-9_-]+)$/i.exec(sel))
|
||||||
|
res = function (elem) elem.localName == val;
|
||||||
|
else if (/^#([a-z0-9:_-]+)$/i.exec(sel))
|
||||||
|
res = function (elem) elem.id == val;
|
||||||
|
else if (/^\.([a-z0-9:_-]+)$/i.exec(sel))
|
||||||
|
res = function (elem) elem.classList.contains(val);
|
||||||
|
else if (/^\[([a-z0-9:_-]+)\]$/i.exec(sel))
|
||||||
|
res = function (elem) elem.hasAttribute(val);
|
||||||
|
else
|
||||||
|
res = function (elem) ~Array.indexOf(elem.parentNode.querySelectorAll(sel),
|
||||||
|
elem);
|
||||||
|
|
||||||
|
let val = RegExp.$1;
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
|
||||||
|
each: function each(fn, self) {
|
||||||
|
let obj = self || this.Empty();
|
||||||
|
for (let i = 0; i < this.length; i++)
|
||||||
|
fn.call(self || update(obj, [this[i]]), this[i], i);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
eachDOM: function eachDOM(val, fn, self) {
|
||||||
|
if (typeof val == "xml")
|
||||||
|
return this.each(function (elem, i) {
|
||||||
|
fn.call(this, util.xmlToDom(val, elem.ownerDocument), elem, i);
|
||||||
|
}, self || this);
|
||||||
|
|
||||||
|
let dom = this;
|
||||||
|
function munge(val) {
|
||||||
|
if (typeof val == "xml")
|
||||||
|
val = dom.constructor(val, dom.document);
|
||||||
|
|
||||||
|
if (isObject(val) && "length" in val) {
|
||||||
|
let frag = dom.document.createDocumentFragment();
|
||||||
|
for (let i = 0; i < val.length; i++)
|
||||||
|
frag.appendChild(val[i]);
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callable(val))
|
||||||
|
return this.each(function (elem, i) {
|
||||||
|
fn.call(this, munge(val.call(this, elem, i)), elem, i);
|
||||||
|
}, self || this);
|
||||||
|
|
||||||
|
fn.call(self || this, munge(val), this[0], 0);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
eq: function eq(idx) {
|
||||||
|
return this.constructor(this[idx >= 0 ? idx : this.length + idx]);
|
||||||
|
},
|
||||||
|
|
||||||
|
find: function find(val) {
|
||||||
|
return this.map(function (elem) elem.querySelectorAll(val));
|
||||||
|
},
|
||||||
|
|
||||||
|
filter: function filter(val, self) {
|
||||||
|
let res = this.Empty();
|
||||||
|
|
||||||
|
if (!callable(val))
|
||||||
|
val = this.matcher(val);
|
||||||
|
|
||||||
|
this.constructor(Array.filter(this, val, self || this));
|
||||||
|
for (let i = 0; i < this.length; i++)
|
||||||
|
if (val.call(self, this[i], i))
|
||||||
|
res[res.length++] = this[i];
|
||||||
|
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
|
||||||
|
is: function is(val) {
|
||||||
|
return this.some(this.matcher(val));
|
||||||
|
},
|
||||||
|
|
||||||
|
reverse: function reverse() {
|
||||||
|
Array.reverse(this);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
all: function all(fn, self) {
|
||||||
|
let res = this.Empty();
|
||||||
|
|
||||||
|
this.each(function (elem) {
|
||||||
|
while((elem = fn.call(this, elem)) instanceof Ci.nsIDOMElement)
|
||||||
|
res[res.length++] = elem;
|
||||||
|
}, self || this);
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
|
||||||
|
map: function map(fn, self) {
|
||||||
|
let res = this.Empty();
|
||||||
|
let obj = self || this.Empty();
|
||||||
|
|
||||||
|
for (let i = 0; i < this.length; i++) {
|
||||||
|
let tmp = fn.call(self || update(obj, [this[i]]), this[i], i);
|
||||||
|
if ("length" in tmp)
|
||||||
|
for (let j = 0; j < tmp.length; j++)
|
||||||
|
res[res.length++] = tmp[j];
|
||||||
|
else
|
||||||
|
res[res.length++] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
|
||||||
|
slice: function eq(start, end) {
|
||||||
|
return this.constructor(Array.slice(this, start, end));
|
||||||
|
},
|
||||||
|
|
||||||
|
some: function some(fn, self) {
|
||||||
|
for (let i = 0; i < this.length; i++)
|
||||||
|
if (fn.call(self || this, this[i], i))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
get parent() this.map(function (elem) elem.parentNode, this),
|
||||||
|
|
||||||
|
get ancestors() this.all(function (elem) elem.parentNode),
|
||||||
|
|
||||||
|
get children() this.map(function (elem) Array.filter(elem.childNodes,
|
||||||
|
function (e) e instanceof Ci.nsIDOMElement),
|
||||||
|
this),
|
||||||
|
|
||||||
|
get contents() this.map(function (elem) elem.childNodes, this),
|
||||||
|
|
||||||
|
get siblings() this.map(function (elem) Array.filter(elem.parentNode.childNodes,
|
||||||
|
function (e) e != elem && e instanceof Ci.nsIDOMElement),
|
||||||
|
this),
|
||||||
|
|
||||||
|
get siblingsBefore() this.all(function (elem) elem.previousElementSibling),
|
||||||
|
get siblingsAfter() this.all(function (elem) elem.nextElementSibling),
|
||||||
|
|
||||||
|
get class() let (self = this) ({
|
||||||
|
toString: function () self[0].className,
|
||||||
|
|
||||||
|
get list() Array.slice(self[0].classList),
|
||||||
|
set list(val) self.attr("class", val.join(" ")),
|
||||||
|
|
||||||
|
each: function each(meth, arg) {
|
||||||
|
return self.each(function (elem) {
|
||||||
|
elem.classList[meth](arg);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
add: function add(cls) this.each("add", cls),
|
||||||
|
remove: function remove(cls) this.each("remove", cls),
|
||||||
|
toggle: function toggle(cls) this.each("toggle", cls),
|
||||||
|
|
||||||
|
has: function has(cls) this[0].classList.has(cls)
|
||||||
|
}),
|
||||||
|
|
||||||
|
get highlight() let (self = this) ({
|
||||||
|
toString: function () self.attrNS(NS, "highlight") || "",
|
||||||
|
|
||||||
|
get list() this.toString().trim().split(/\s+/),
|
||||||
|
set list(val) self.attrNS(NS, "highlight", val.join(" ")),
|
||||||
|
|
||||||
|
has: function has(hl) ~this.list.indexOf(hl),
|
||||||
|
|
||||||
|
add: function add(hl) self.each(function () {
|
||||||
|
this.attrNS(NS, "highlight",
|
||||||
|
array.uniq(this.highlight.list.concat(hl)).join(" "));
|
||||||
|
}),
|
||||||
|
|
||||||
|
remove: function remove(hl) self.each(function () {
|
||||||
|
this.attrNS(NS, "highlight",
|
||||||
|
this.highlight.list.filter(function (h) h != hl));
|
||||||
|
}),
|
||||||
|
|
||||||
|
toggle: function toggle(hl) self.each(function () {
|
||||||
|
let { highlight } = this;
|
||||||
|
highlight[highlight.has(hl) ? "remove" : "add"](hl)
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
|
||||||
|
get rect() this[0].getBoundingClientRect(),
|
||||||
|
|
||||||
|
get style() util.computedStyle(this[0]),
|
||||||
|
|
||||||
|
attr: function attr(key, val) {
|
||||||
|
return this.attrNS("", key, val);
|
||||||
|
},
|
||||||
|
|
||||||
|
attrNS: function attrNS(ns, key, val) {
|
||||||
|
if (val !== undefined)
|
||||||
|
key = array.toObject([[key, val]]);
|
||||||
|
|
||||||
|
let hooks = this.attrHooks[ns] || {};
|
||||||
|
|
||||||
|
if (isObject(key))
|
||||||
|
return this.each(function (elem) {
|
||||||
|
for (let [k, v] in Iterator(key))
|
||||||
|
if (Set.has(hooks, k) && hooks[k].set)
|
||||||
|
hooks[k].set.call(this, elem, v);
|
||||||
|
else if (v == null)
|
||||||
|
elem.removeAttributeNS(ns, k);
|
||||||
|
else
|
||||||
|
elem.setAttributeNS(ns, k, v);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (Set.has(hooks, k) && hooks[k].get)
|
||||||
|
return hooks[k].get.call(this, elem);
|
||||||
|
|
||||||
|
if (!this[0].hasAttributeNS(ns, key))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return this[0].getAttributeNS(ns, key);
|
||||||
|
},
|
||||||
|
|
||||||
|
css: update(function css(key, val) {
|
||||||
|
if (val !== undefined)
|
||||||
|
key = array.toObject([[key, val]]);
|
||||||
|
|
||||||
|
if (isObject(key))
|
||||||
|
return this.each(function (elem) {
|
||||||
|
for (let [k, v] in Iterator(key))
|
||||||
|
elem.style[css.property(k)] = v;
|
||||||
|
});
|
||||||
|
|
||||||
|
return this[0].style[css.property(key)];
|
||||||
|
}, {
|
||||||
|
name: function (property) property.replace(/[A-Z]/g, function (m0) "-" + m0.toLowerCase()),
|
||||||
|
|
||||||
|
property: function (name) name.replace(/-(.)/g, function (m0, m1) m1.toUpperCase())
|
||||||
|
}),
|
||||||
|
|
||||||
|
append: function append(val) {
|
||||||
|
return this.eachDOM(val, function (elem, target) {
|
||||||
|
target.appendChild(elem);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
prepend: function prepend(val) {
|
||||||
|
return this.eachDOM(val, function (elem, target) {
|
||||||
|
target.insertBefore(elem, target.firstChild);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
before: function before(val) {
|
||||||
|
return this.eachDOM(val, function (elem, target) {
|
||||||
|
target.parentNode.insertBefore(elem, target);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
after: function after(val) {
|
||||||
|
return this.eachDOM(val, function (elem, target) {
|
||||||
|
target.parentNode.insertBefore(elem, target.nextSibling);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
appendTo: function appendTo(elem) {
|
||||||
|
if (!(elem instanceof this.constructor))
|
||||||
|
elem = this.constructor(elem, this.document);
|
||||||
|
elem.append(this);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
prependTo: function appendTo(elem) {
|
||||||
|
if (!(elem instanceof this.constructor))
|
||||||
|
elem = this.constructor(elem, this.document);
|
||||||
|
elem.prepend(this);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
insertBefore: function insertBefore(elem) {
|
||||||
|
if (!(elem instanceof this.constructor))
|
||||||
|
elem = this.constructor(elem, this.document);
|
||||||
|
elem.before(this);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
insertAfter: function insertAfter(elem) {
|
||||||
|
if (!(elem instanceof this.constructor))
|
||||||
|
elem = this.constructor(elem, this.document);
|
||||||
|
elem.after(this);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
remove: function remove() {
|
||||||
|
return this.each(function (elem) {
|
||||||
|
if (elem.parentNode)
|
||||||
|
elem.parentNode.removeChild(elem);
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
empty: function empty() {
|
||||||
|
return this.each(function (elem) {
|
||||||
|
while (elem.firstChild)
|
||||||
|
elem.removeChild(elem.firstChild);
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
toggle: function toggle(val) {
|
||||||
|
if (arguments.length)
|
||||||
|
return this[val ? "show" : "hide"]();
|
||||||
|
return this.each(function (elem) {
|
||||||
|
elem.style.display = this.style.display == "none" ? "block" : "none";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
hide: function hide() {
|
||||||
|
return this.each(function (elem) { elem.style.display = "none"; }, this);
|
||||||
|
},
|
||||||
|
show: function show() {
|
||||||
|
return this.each(function (elem) { elem.style.display = "block"; }, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
getSet: function getSet(args, get, set) {
|
||||||
|
if (!args.length)
|
||||||
|
return get.call(this, this[0]);
|
||||||
|
|
||||||
|
let [fn, self] = args;
|
||||||
|
if (!callable(fn))
|
||||||
|
fn = function () args[0];
|
||||||
|
|
||||||
|
return this.each(function (elem, i) {
|
||||||
|
set.call(this, elem, fn.call(self || this, elem, i));
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
html: function html(txt, self) {
|
||||||
|
return this.getSet(arguments,
|
||||||
|
function (elem) elem.innerHTML,
|
||||||
|
function (elem, val) { elem.innerHTML = val });
|
||||||
|
},
|
||||||
|
|
||||||
|
text: function text(txt, self) {
|
||||||
|
return this.getSet(arguments,
|
||||||
|
function (elem) elem.textContent,
|
||||||
|
function (elem, val) { elem.textContent = val });
|
||||||
|
},
|
||||||
|
|
||||||
|
val: function val(txt) {
|
||||||
|
return this.getSet(arguments,
|
||||||
|
function (elem) elem.value,
|
||||||
|
function (elem, val) { elem.value = val });
|
||||||
|
},
|
||||||
|
|
||||||
|
listen: function listen(event, listener, capture) {
|
||||||
|
if (isObject(event))
|
||||||
|
capture = listener;
|
||||||
|
else
|
||||||
|
event = array.toObject([[event, listener]]);
|
||||||
|
|
||||||
|
for (let [k, v] in Iterator(event))
|
||||||
|
event[k] = util.wrapCallback(v);
|
||||||
|
|
||||||
|
return this.each(function (elem) {
|
||||||
|
for (let [k, v] in Iterator(event))
|
||||||
|
elem.addEventListener(k, v, capture);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
unlisten: function unlisten(event, listener, capture) {
|
||||||
|
if (isObject(event))
|
||||||
|
capture = listener;
|
||||||
|
else
|
||||||
|
event = array.toObject([[key, val]]);
|
||||||
|
|
||||||
|
return this.each(function (elem) {
|
||||||
|
for (let [k, v] in Iterator(event))
|
||||||
|
elem.removeEventListener(k, v.wrapper || v, capture);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
dispatch: function dispatch(event, params, extraProps) {
|
||||||
|
return this.each(function (elem) {
|
||||||
|
let evt = DOM.Event(this.document, event, params);
|
||||||
|
DOM.Event.dispatch(elem, evt, extraProps);
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
focus: function focus(arg, extra) {
|
||||||
|
if (callable(arg))
|
||||||
|
return this.listen("focus", arg, extra);
|
||||||
|
services.focus.setFocus(this[0], extra || services.focus.FLAG_BYMOUSE);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
blur: function blur(arg, extra) {
|
||||||
|
if (callable(arg))
|
||||||
|
return this.listen("blur", arg, extra);
|
||||||
|
return this.each(function (elem) { elem.blur(); }, this);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
/**
|
||||||
|
* Creates an actual event from a pseudo-event object.
|
||||||
|
*
|
||||||
|
* The pseudo-event object (such as may be retrieved from events.fromString)
|
||||||
|
* should have any properties you want the event to have.
|
||||||
|
*
|
||||||
|
* @param {Document} doc The DOM document to associate this event with
|
||||||
|
* @param {Type} type The type of event (keypress, click, etc.)
|
||||||
|
* @param {Object} opts The pseudo-event. @optional
|
||||||
|
*/
|
||||||
|
Event: Class("Event", {
|
||||||
|
init: function Event(doc, type, opts) {
|
||||||
|
const DEFAULTS = {
|
||||||
|
HTML: {
|
||||||
|
type: type, bubbles: true, cancelable: false
|
||||||
|
},
|
||||||
|
Key: {
|
||||||
|
type: type,
|
||||||
|
bubbles: true, cancelable: true,
|
||||||
|
view: doc.defaultView,
|
||||||
|
ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
|
||||||
|
keyCode: 0, charCode: 0
|
||||||
|
},
|
||||||
|
Mouse: {
|
||||||
|
type: type,
|
||||||
|
bubbles: true, cancelable: true,
|
||||||
|
view: doc.defaultView,
|
||||||
|
detail: 1,
|
||||||
|
screenX: 0, screenY: 0,
|
||||||
|
clientX: 0, clientY: 0,
|
||||||
|
ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
|
||||||
|
button: 0,
|
||||||
|
relatedTarget: null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
opts = opts || {};
|
||||||
|
|
||||||
|
var t = this.constructor.types[type];
|
||||||
|
var evt = doc.createEvent((t || "HTML") + "Events");
|
||||||
|
|
||||||
|
let defaults = DEFAULTS[t || "HTML"];
|
||||||
|
|
||||||
|
let args = Object.keys(defaults)
|
||||||
|
.map(function (k) k in opts ? opts[k] : defaults[k]);
|
||||||
|
|
||||||
|
evt["init" + t + "Event"].apply(evt, args);
|
||||||
|
return evt;
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
types: Class.memoize(function () iter(
|
||||||
|
{
|
||||||
|
Mouse: "click mousedown mouseout mouseover mouseup",
|
||||||
|
Key: "keydown keypress keyup",
|
||||||
|
"": "change dactyl-input input submit"
|
||||||
|
}
|
||||||
|
).map(function ([k, v]) v.split(" ").map(function (v) [v, k]))
|
||||||
|
.flatten()
|
||||||
|
.toObject()),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatches an event to an element as if it were a native event.
|
||||||
|
*
|
||||||
|
* @param {Node} target The DOM node to which to dispatch the event.
|
||||||
|
* @param {Event} event The event to dispatch.
|
||||||
|
*/
|
||||||
|
dispatch: Class.memoize(function ()
|
||||||
|
util.haveGecko("2b")
|
||||||
|
? function dispatch(target, event, extra) {
|
||||||
|
try {
|
||||||
|
this.feedingEvent = extra;
|
||||||
|
|
||||||
|
if (target instanceof Ci.nsIDOMElement)
|
||||||
|
// This causes a crash on Gecko<2.0, it seems.
|
||||||
|
return (target.ownerDocument || target.document || target).defaultView
|
||||||
|
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils)
|
||||||
|
.dispatchDOMEventViaPresShell(target, event, true);
|
||||||
|
else {
|
||||||
|
target.dispatchEvent(event);
|
||||||
|
return !event.getPreventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
util.reportError(e);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
this.feedingEvent = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: function dispatch(target, event, extra) {
|
||||||
|
try {
|
||||||
|
this.feedingEvent = extra;
|
||||||
|
target.dispatchEvent(update(event, extra));
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
this.feedingEvent = null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(DOM.Event.types).forEach(function (event) {
|
||||||
|
DOM.prototype[util.camelCase(event)] = function _event(arg, extra) {
|
||||||
|
return this[callable(arg) ? "listen" : "dispatch"](event, arg, extra);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
var $ = DOM;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Math utility methods.
|
* Math utility methods.
|
||||||
* @singleton
|
* @singleton
|
||||||
|
|||||||
Reference in New Issue
Block a user