mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-20 10:57:58 +01:00
Add experimental jQuery-ish DOM object.
This commit is contained in:
@@ -491,7 +491,7 @@ var Buffer = Module("buffer", {
|
||||
try {
|
||||
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) {}
|
||||
}
|
||||
@@ -606,13 +606,15 @@ var Buffer = Module("buffer", {
|
||||
|
||||
prefs.withContext(function () {
|
||||
prefs.set("browser.tabs.loadInBackground", true);
|
||||
["mousedown", "mouseup", "click"].slice(0, util.haveGecko("2b") ? 2 : 3)
|
||||
.forEach(function (event) {
|
||||
events.dispatch(elem, events.create(doc, event, {
|
||||
screenX: offsetX, screenY: offsetY,
|
||||
ctrlKey: ctrlKey, shiftKey: shiftKey, metaKey: ctrlKey
|
||||
}));
|
||||
});
|
||||
let params = {
|
||||
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);
|
||||
sel.getSelection(sel.SELECTION_FOCUS_REGION).collapseToStart();
|
||||
});
|
||||
@@ -1422,8 +1424,7 @@ var Buffer = Module("buffer", {
|
||||
let file = io.File(path);
|
||||
dactyl.assert(file.exists());
|
||||
|
||||
elem.value = file.path;
|
||||
events.dispatch(elem, events.create(elem.ownerDocument, "change", {}));
|
||||
DOM(elem).val(file.path).change();
|
||||
}
|
||||
}).open(elem.value);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ var Editor = Module("editor", {
|
||||
elem.scrollTop = top;
|
||||
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;
|
||||
|
||||
if (false) {
|
||||
textBox.setAttributeNS(NS, "modifiable", true);
|
||||
util.computedStyle(textBox).MozUserInput;
|
||||
events.dispatch(textBox, events.create(textBox.ownerDocument, "input", {}));
|
||||
textBox.removeAttributeNS(NS, "modifiable");
|
||||
let elem = DOM(textBox);
|
||||
elem.attrNS(NS, "modifiable", true)
|
||||
.style.MozUserInput;
|
||||
elem.input().attrNS(NS, "modifiable", null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -641,8 +641,8 @@ var Events = Module("events", {
|
||||
let elem = target || event.originalTarget;
|
||||
if (elem) {
|
||||
let doc = elem.ownerDocument || elem.document || elem;
|
||||
let evt = events.create(doc, event.type, event);
|
||||
events.dispatch(elem, evt, extra);
|
||||
let evt = DOM.Event(doc, event.type, event);
|
||||
DOM.Event.dispatch(elem, evt, extra);
|
||||
}
|
||||
else if (i > 0 && event.type === "keypress")
|
||||
events.events.keypress.call(events, event);
|
||||
@@ -691,10 +691,10 @@ var Events = Module("events", {
|
||||
evt.isMacro = true;
|
||||
evt.dactylMode = mode;
|
||||
evt.dactylSavedEvents = savedEvents;
|
||||
this.feedingEvent = evt;
|
||||
DOM.Event.feedingEvent = evt;
|
||||
|
||||
let doc = document.commandDispatcher.focusedWindow.document;
|
||||
let event = events.create(doc, type, evt);
|
||||
|
||||
let target = dactyl.focusedElement
|
||||
|| ["complete", "interactive"].indexOf(doc.readyState) >= 0 && doc.documentElement
|
||||
|| doc.defaultView;
|
||||
@@ -703,6 +703,7 @@ var Events = Module("events", {
|
||||
["<Return>", "<Space>"].indexOf(key) == -1)
|
||||
target = target.ownerDocument.documentElement;
|
||||
|
||||
let event = DOM.Event(doc, type, evt);
|
||||
if (!evt_obj.dactylString && !mode)
|
||||
events.dispatch(target, event, evt);
|
||||
else if (type === "keypress")
|
||||
@@ -717,7 +718,7 @@ var Events = Module("events", {
|
||||
util.reportError(e);
|
||||
}
|
||||
finally {
|
||||
this.feedingEvent = null;
|
||||
DOM.Event.feedingEvent = null;
|
||||
this.feedingKeys = wasFeeding;
|
||||
if (quiet)
|
||||
commandline.quiet = wasQuiet;
|
||||
@@ -726,64 +727,8 @@ var Events = Module("events", {
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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()),
|
||||
create: deprecated("DOM.Event", function create() DOM.Event.apply(null, arguments)),
|
||||
dispatch: deprecated("DOM.Event.dispatch", function dispatch() DOM.Event.dispatch.apply(DOM.Event, arguments)),
|
||||
|
||||
/**
|
||||
* Converts a user-input string of keys into a canonical
|
||||
@@ -817,44 +762,6 @@ var Events = Module("events", {
|
||||
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,
|
||||
|
||||
/**
|
||||
@@ -1306,11 +1213,11 @@ var Events = Module("events", {
|
||||
let duringFeed = this.duringFeed || [];
|
||||
this.duringFeed = [];
|
||||
try {
|
||||
if (this.feedingEvent)
|
||||
for (let [k, v] in Iterator(this.feedingEvent))
|
||||
if (DOM.Event.feedingEvent)
|
||||
for (let [k, v] in Iterator(DOM.Event.feedingEvent))
|
||||
if (!(k in event))
|
||||
event[k] = v;
|
||||
this.feedingEvent = null;
|
||||
DOM.Event.feedingEvent = null;
|
||||
|
||||
let key = events.toString(event);
|
||||
|
||||
@@ -1321,7 +1228,7 @@ var Events = Module("events", {
|
||||
elem.dactylKeyPress = elem.value;
|
||||
util.timeout(function () {
|
||||
if (elem.dactylKeyPress !== undefined && elem.value !== elem.dactylKeyPress)
|
||||
events.dispatch(elem, events.create(elem.ownerDocument, "dactyl-input"));
|
||||
DOM(elem).dactylInput();
|
||||
elem.dactylKeyPress = undefined;
|
||||
});
|
||||
}
|
||||
@@ -1425,7 +1332,7 @@ var Events = Module("events", {
|
||||
this.keyEvents = [];
|
||||
|
||||
let pass = this.passing && !event.isMacro ||
|
||||
this.feedingEvent && this.feedingEvent.isReplay ||
|
||||
DOM.Event.feedingEvent && DOM.Event.feedingEvent.isReplay ||
|
||||
event.isReplay ||
|
||||
modes.main == modes.PASS_THROUGH ||
|
||||
modes.main == modes.QUOTE
|
||||
|
||||
@@ -731,8 +731,10 @@ var Styles = Module("Styles", {
|
||||
template.highlightCSS = function highlightCSS(css) {
|
||||
XML.prettyPrinting = XML.ignoreWhitespace = false;
|
||||
|
||||
return this.highlightRegexp(css, patterns.property, function (match) <>{
|
||||
match.preSpace}{template.filter(match.name)}: {
|
||||
return this.highlightRegexp(css, patterns.property, function (match) {
|
||||
if (!match.length)
|
||||
return <></>;
|
||||
return <>{match.preSpace}{template.filter(match.name)}: {
|
||||
|
||||
template.highlightRegexp(match.value, patterns.token, function (match) {
|
||||
if (match.function)
|
||||
@@ -749,7 +751,7 @@ var Styles = Module("Styles", {
|
||||
})
|
||||
|
||||
}{ match.postSpace }</>
|
||||
)
|
||||
})
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ try {
|
||||
Components.utils.import("resource://dactyl/bootstrap.jsm");
|
||||
let frag=1;
|
||||
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"],
|
||||
use: ["commands", "config", "highlight", "messages", "storage", "template"]
|
||||
}, this);
|
||||
@@ -37,15 +37,16 @@ var FailedAssertion = Class("FailedAssertion", ErrorBase, {
|
||||
var Point = Struct("x", "y");
|
||||
|
||||
var wrapCallback = function wrapCallback(fn) {
|
||||
fn.wrapper = function wrappedCallback () {
|
||||
try {
|
||||
return fn.apply(this, arguments);
|
||||
}
|
||||
catch (e) {
|
||||
util.reportError(e);
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
if (!fn.wrapper)
|
||||
fn.wrapper = function wrappedCallback() {
|
||||
try {
|
||||
return fn.apply(this, arguments);
|
||||
}
|
||||
catch (e) {
|
||||
util.reportError(e);
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
fn.wrapper.wrapped = fn;
|
||||
return fn.wrapper;
|
||||
}
|
||||
@@ -161,6 +162,14 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
|
||||
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.
|
||||
* @param {string} str The string to capitalize
|
||||
@@ -2127,6 +2136,552 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
|
||||
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.
|
||||
* @singleton
|
||||
|
||||
Reference in New Issue
Block a user