-// Copyright (c) 2009-2011 by Kris Maglione <maglione.k@gmail.com>
+// Copyright (c) 2009-2012 Kris Maglione <maglione.k@gmail.com>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-/* use strict */
+"use strict";
var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
-Cu.import("resource://dactyl/bootstrap.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
try {
var ctypes;
Cu.import("resource://gre/modules/ctypes.jsm");
if (typeof XPCSafeJSObjectWrapper === "undefined")
this.XPCSafeJSObjectWrapper = XPCNativeWrapper;
-if (!XPCNativeWrapper.unwrap)
- XPCNativeWrapper.unwrap = function unwrap(obj) {
- if (hasOwnProperty.call(obj, "wrappedJSObject"))
- return obj.wrappedJSObject;
- return obj;
- };
-if (!Object.create)
- Object.create = function create(proto, props) {
- let obj = { __proto__: proto };
- for (let k in properties(props || {}))
- Object.defineProperty(obj, k, props[k]);
- return obj;
- };
-if (!Object.defineProperty)
- Object.defineProperty = function defineProperty(obj, prop, desc) {
- try {
- let value = desc.value;
- if ("value" in desc)
- if (desc.writable && !__lookupGetter__.call(obj, prop)
- && !__lookupSetter__.call(obj, prop))
- try {
- obj[prop] = value;
- }
- catch (e if e instanceof TypeError) {}
- else {
- __defineGetter__.call(obj, prop, function () value);
- if (desc.writable)
- __defineSetter__.call(obj, prop, function (val) { value = val; });
- }
+let getGlobalForObject = Cu.getGlobalForObject || function (obj) obj.__parent__;
- if ("get" in desc)
- __defineGetter__.call(obj, prop, desc.get);
- if ("set" in desc)
- __defineSetter__.call(obj, prop, desc.set);
- }
- catch (e) {
- throw e.stack ? e : Error(e);
- }
- };
-if (!Object.defineProperties)
- Object.defineProperties = function defineProperties(obj, props) {
- for (let [k, v] in Iterator(props))
- Object.defineProperty(obj, k, v);
- };
-if (!Object.freeze)
- Object.freeze = function freeze(obj) {};
-if (!Object.getPropertyDescriptor)
- Object.getPropertyDescriptor = function getPropertyDescriptor(obj, prop) {
- try {
- let desc = {
- configurable: true,
- enumerable: propertyIsEnumerable.call(obj, prop)
- };
- var get = __lookupGetter__.call(obj, prop),
- set = __lookupSetter__.call(obj, prop);
- if (!get && !set) {
- desc.value = obj[prop];
- desc.writable = true;
- }
- if (get)
- desc.get = get;
- if (set)
- desc.set = set;
- return desc;
- }
- catch (e) {
- throw e.stack ? e : Error(e);
- }
- };
-if (!Object.getOwnPropertyDescriptor)
- Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(obj, prop) {
- if (hasOwnProperty.call(obj, prop))
- return Object.getPropertyDescriptor(obj, prop);
- };
-if (!Object.getOwnPropertyNames)
- Object.getOwnPropertyNames = function getOwnPropertyNames(obj, _debugger) {
- try {
- // This is an ugly and unfortunately necessary hack.
- if (hasOwnProperty.call(obj, "__iterator__")) {
- var oldIter = obj.__iterator__;
- delete obj.__iterator__;
- }
- let res = [k for (k in obj) if (hasOwnProperty.call(obj, k))];
- if (oldIter !== undefined) {
- obj.__iterator__ = oldIter;
- res.push("__iterator__");
- }
- return res;
- }
- catch (e) {
- throw e.stack ? e : Error(e);
- }
- };
-if (!Object.getPrototypeOf)
- Object.getPrototypeOf = function getPrototypeOf(obj) obj.__proto__;
-if (!Object.keys)
- Object.keys = function keys(obj)
- Object.getOwnPropertyNames(obj).filter(function (k) propertyIsEnumerable.call(obj, k));
+function require(module, target) JSMLoader.load(module, target);
-let getGlobalForObject = Cu.getGlobalForObject || function (obj) obj.__parent__;
+function lazyRequire(module, names, target) {
+ for each (let name in names)
+ memoize(target || this, name, function (name) require(module)[name]);
+}
-let jsmodules = {
- lazyRequire: function lazyRequire(module, names, target) {
- for each (let name in names)
- memoize(target || this, name, function (name) require(module)[name]);
- }
-};
+let jsmodules = { lazyRequire: lazyRequire };
jsmodules.jsmodules = jsmodules;
+function toString() "[module-global " + this.NAME + "]";
+
let use = {};
let loaded = {};
let currentModule;
let global = this;
function defineModule(name, params, module) {
if (!module)
- module = getGlobalForObject(params);
+ module = this;
module.NAME = name;
module.EXPORTED_SYMBOLS = params.exports || [];
defineModule.prefix += " ";
for (let [, mod] in Iterator(params.require || []))
- require(module, mod, null, name);
- module.__proto__ = jsmodules;
+ require(mod, module);
module._lastModule = currentModule;
currentModule = module;
Object.defineProperty(defineModule.loadLog, "push", {
value: function (val) {
val = defineModule.prefix + val;
- if (false)
+ if (true)
defineModule.dump(val + "\n");
this[this.length] = Date.now() + " " + val;
}
defineModule.loadLog.push("(End " + currentModule.NAME + ")");
loaded[currentModule.NAME] = 1;
- require(jsmodules, currentModule.NAME);
+ require(currentModule.NAME, jsmodules);
currentModule = currentModule._lastModule;
}
-function require(obj, name, from, targetName) {
+function require_(obj, name, from, targetName) {
try {
if (arguments.length === 1)
[obj, name] = [{}, obj];
defineModule("base", {
// sed -n 's/^(const|var|function) ([a-zA-Z0-9_]+).*/ "\2",/p' base.jsm | sort | fmt
exports: [
- "ErrorBase", "Cc", "Ci", "Class", "Cr", "Cu", "Module", "JSMLoader", "Object",
+ "ErrorBase", "Cc", "Ci", "Class", "Cr", "Cu", "Finished", "Module", "JSMLoader",
"Set", "Struct", "StructBase", "Timer", "UTF8", "XPCOM", "XPCOMShim", "XPCOMUtils",
"XPCSafeJSObjectWrapper", "array", "bind", "call", "callable", "ctypes", "curry",
"debuggerProperties", "defineModule", "deprecated", "endModule", "forEach", "isArray",
- "isGenerator", "isinstance", "isObject", "isString", "isSubclass", "iter", "iterAll",
- "iterOwnProperties", "keys", "memoize", "octal", "properties", "require", "set", "update",
- "values", "withCallerGlobal"
+ "isGenerator", "isinstance", "isObject", "isString", "isSubclass", "isXML", "iter",
+ "iterAll", "iterOwnProperties", "keys", "literal", "memoize", "octal", "properties",
+ "require", "set", "update", "values", "update_"
]
-}, this);
+});
+this.lazyRequire("cache", ["cache"]);
+this.lazyRequire("config", ["config"]);
this.lazyRequire("messages", ["_", "Messages"]);
-this.lazyRequire("util", ["util"]);
+this.lazyRequire("services", ["services"]);
+this.lazyRequire("storage", ["File"]);
+this.lazyRequire("util", ["FailedAssertion", "util"]);
+
+function literal(/* comment */) {
+ let { caller } = Components.stack;
+ while (caller && caller.language != 2)
+ caller = caller.caller;
+
+ let file = caller.filename.replace(/.* -> /, "");
+ let key = "literal:" + file + ":" + caller.line;
+
+ let source = File.readURL(file);
+
+ let match = RegExp("(?:.*\\n){" + (caller.lineNumber - 1) + "}" +
+ ".*literal\\(/\\*([^]*?)\\*/\\)").exec(source);
+ return match[1];
+
+ // Later...
+ return cache.get(key, function () {
+ let source = cache.get("literal:" + file,
+ function () util.httpGet(file).responseText);
+
+ let match = RegExp("(?:.*\\n){" + (caller.lineNumber - 1) + "}" +
+ ".*literal\\(/\\*([^]*?)\\*/\\)").exec(source);
+ return match[1];
+ });
+}
/**
* Returns a list of all of the top-level properties of an object, by
* @returns {Generator}
*/
function prototype(obj)
- /* Temporary hack: */ typeof obj === "xml" || obj.__proto__ !== obj.__proto__ ? null :
obj.__proto__ || Object.getPrototypeOf(obj) ||
XPCNativeWrapper.unwrap(obj).__proto__ ||
Object.getPrototypeOf(XPCNativeWrapper.unwrap(obj));
}
catch (e) {}
+ function props(obj) {
+ // Grr.
+ try {
+ return Object.getOwnPropertyNames(obj);
+ }
+ catch (e) {
+ if (e.result === Cr.NS_ERROR_FAILURE) {
+ // This is being thrown for PDF.js content windows,
+ // currently.
+ let filter = function filter(prop) {
+ try {
+ return prop in obj;
+ }
+ catch (e) {
+ util.reportError("Filtering properties for " +
+ String.quote(obj) + ", " +
+ "error checking presence of " +
+ String.quote(prop) + ": " + e);
+ }
+ return false;
+ };
+ return array.uniq([k for (k in obj)].concat(
+ Object.getOwnPropertyNames(
+ XPCNativeWrapper.unwrap(obj))
+ .filter(filter)))
+ }
+ else if (!e.stack) {
+ throw Error(e);
+ }
+ }
+ }
+
for (; obj; obj = prototypes && prototype(obj)) {
try {
- if (sandbox.Object.getOwnPropertyNames || !debugger_ || !services.debugger.isOn)
- var iter = (v for each (v in Object.getOwnPropertyNames(obj)));
+ if (!debugger_ || !services.debugger.isOn)
+ var iter = (v for each (v in props(obj)));
}
catch (e) {}
if (!iter)
deprecated.warn = function warn(func, name, alternative, frame) {
if (!func.seenCaller)
func.seenCaller = Set([
- "resource://dactyl" + JSMLoader.suffix + "/javascript.jsm",
- "resource://dactyl" + JSMLoader.suffix + "/util.jsm"
+ "resource://dactyl/javascript.jsm",
+ "resource://dactyl/util.jsm"
]);
frame = frame || Components.stack.caller.caller;
*/
function isObject(obj) typeof obj === "object" && obj != null || obj instanceof Ci.nsISupports;
+/**
+ * Returns true if obje is an E4X XML object.
+ * @deprecated
+ */
+function isXML(obj) typeof obj === "xml";
+
/**
* Returns true if and only if its sole argument is an
* instance of the builtin Array type. The array may come from
}
}
-let sandbox = Cu.Sandbox(this);
+let sandbox = Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"].createInstance());
sandbox.__proto__ = this;
-/**
- * Wraps a function so that when called, the global object of the caller
- * is prepended to its arguments.
- */
-// Hack to get around lack of access to caller in strict mode.
-var withCallerGlobal = Cu.evalInSandbox(<![CDATA[
- (function withCallerGlobal(fn)
- function withCallerGlobal_wrapped()
- fn.apply(this,
- [Class.objectGlobal(withCallerGlobal_wrapped.caller)]
- .concat(Array.slice(arguments))))
-]]>, Cu.Sandbox(this), "1.8");
/**
* Updates an object with the properties of another object. Getters
if (typeof desc.value === "function" && target.__proto__ && !(desc.value instanceof Ci.nsIDOMElement /* wtf? */)) {
let func = desc.value.wrapped || desc.value;
if (!func.superapply) {
- func.__defineGetter__("super", function () Object.getPrototypeOf(target)[k]);
+ func.__defineGetter__("super", function get_super() Object.getPrototypeOf(target)[k]);
func.superapply = function superapply(self, args)
let (meth = Object.getPrototypeOf(target)[k])
meth && meth.apply(self, args);
}
return target;
}
+function update_(target) {
+ for (let i = 1; i < arguments.length; i++) {
+ let src = arguments[i];
+ Object.getOwnPropertyNames(src || {}).forEach(function (k) {
+ let desc = Object.getOwnPropertyDescriptor(src, k);
+ if (desc.value instanceof Class.Property)
+ desc = desc.value.init(k, target) || desc.value;
+
+ try {
+ if (typeof desc.value === "function" && target.__proto__ && !(desc.value instanceof Ci.nsIDOMElement /* wtf? */)) {
+ let func = desc.value.wrapped || desc.value;
+ if (!func.superapply) {
+ func.__defineGetter__("super", function get_super_() Object.getPrototypeOf(target)[k]);
+ func.superapply = function super_apply(self, args)
+ let (meth = Object.getPrototypeOf(target)[k])
+ meth && meth.apply(self, args);
+ func.supercall = function super_call(self)
+ func.superapply(self, Array.slice(arguments, 1));
+ }
+ }
+ Object.defineProperty(target, k, desc);
+ }
+ catch (e) {}
+ });
+ }
+ return target;
+}
/**
* @constructor Class
var Constructor = function Constructor() {
var self = Object.create(Constructor.prototype);
self.instance = self;
+ self.globalInstance = self;
if ("_metaInit_" in self && self._metaInit_)
self._metaInit_.apply(self, arguments);
return res !== undefined ? res : self;
};
else
- var Constructor = eval(String.replace(<![CDATA[
- (function constructor(PARAMS) {
- var self = Object.create(Constructor.prototype);
- self.instance = self;
-
- if ("_metaInit_" in self && self._metaInit_)
- self._metaInit_.apply(self, arguments);
-
- var res = self.init.apply(self, arguments);
- return res !== undefined ? res : self;
- })]]>,
+ var Constructor = eval(String.replace('\n\
+ (function constructor(PARAMS) { \n\
+ var self = Object.create(Constructor.prototype); \n\
+ self.instance = self; \n\
+ self.globalInstance = self; \n\
+ \n\
+ if ("_metaInit_" in self && self._metaInit_) \n\
+ self._metaInit_.apply(self, arguments); \n\
+ \n\
+ var res = self.init.apply(self, arguments); \n\
+ return res !== undefined ? res : self; \n\
+ })',
"constructor", (name || superclass.className).replace(/\W/g, "_"))
.replace("PARAMS", /^function .*?\((.*?)\)/.exec(args[0] && args[0].init || Class.prototype.init)[1]
.replace(/\b(self|res|Constructor)\b/g, "$1_")));
toString: function () String(this.message)
});
+/**
+ * An Error subclass to throw in order to stop sourcing a plugin without
+ * printing a stack trace.
+ */
+var Finished = Class("Finished", ErrorBase);
+
/**
* Constructs a new Module class and instantiates an instance into the current
* module global object.
}
else if (isinstance(obj, [Ci.nsIDOMHTMLCollection, Ci.nsIDOMNodeList]))
res = array.iterItems(obj);
- else if (obj instanceof Ci.nsIDOMNamedNodeMap)
+ else if (Ci.nsIDOMNamedNodeMap && obj instanceof Ci.nsIDOMNamedNodeMap ||
+ Ci.nsIDOMMozNamedAttrMap && obj instanceof Ci.nsIDOMMozNamedAttrMap)
res = (function () {
for (let i = 0; i < obj.length; i++)
yield [obj.name, obj];