diff --git a/common/content/abbreviations.js b/common/content/abbreviations.js index 09097e0a..1b3f76a3 100644 --- a/common/content/abbreviations.js +++ b/common/content/abbreviations.js @@ -8,7 +8,7 @@ /** @scope modules */ -const Abbreviation = Class("Abbreviation", { +var Abbreviation = Class("Abbreviation", { init: function (modes, lhs, rhs) { this.modes = modes.sort(); this.lhs = lhs; @@ -41,7 +41,7 @@ const Abbreviation = Class("Abbreviation", { } }); -const Abbreviations = Module("abbreviations", { +var Abbreviations = Module("abbreviations", { init: function () { this.abbrevs = {}; diff --git a/common/content/autocommands.js b/common/content/autocommands.js index 66a66f73..802b1ecd 100644 --- a/common/content/autocommands.js +++ b/common/content/autocommands.js @@ -8,12 +8,12 @@ /** @scope modules */ -const AutoCommand = Struct("event", "pattern", "command"); +var AutoCommand = Struct("event", "pattern", "command"); /** * @instance autocommands */ -const AutoCommands = Module("autocommands", { +var AutoCommands = Module("autocommands", { init: function () { this._store = []; }, diff --git a/common/content/bookmarks.js b/common/content/bookmarks.js index 440a65eb..b6643e87 100644 --- a/common/content/bookmarks.js +++ b/common/content/bookmarks.js @@ -6,10 +6,10 @@ // given in the LICENSE.txt file included with this file. "use strict"; -const DEFAULT_FAVICON = "chrome://mozapps/skin/places/defaultFavicon.png"; +var DEFAULT_FAVICON = "chrome://mozapps/skin/places/defaultFavicon.png"; // also includes methods for dealing with keywords and search engines -const Bookmarks = Module("bookmarks", { +var Bookmarks = Module("bookmarks", { init: function () { storage.addObserver("bookmark-cache", function (key, event, arg) { if (["add", "change", "remove"].indexOf(event) >= 0) diff --git a/common/content/browser.js b/common/content/browser.js index 7bc25097..6ceef9bf 100644 --- a/common/content/browser.js +++ b/common/content/browser.js @@ -11,7 +11,7 @@ /** * @instance browser */ -const Browser = Module("browser", { +var Browser = Module("browser", { }, { climbUrlPath: function (count) { let url = util.newURI(buffer.URL); diff --git a/common/content/buffer.js b/common/content/buffer.js index 04dc93ed..5c2f0c97 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -8,7 +8,7 @@ /** @scope modules */ -const Point = Struct("x", "y"); +var Point = Struct("x", "y"); /** * A class to manage the primary web content buffer. The name comes @@ -16,7 +16,7 @@ const Point = Struct("x", "y"); * files. * @instance buffer */ -const Buffer = Module("buffer", { +var Buffer = Module("buffer", { init: function () { this.evaluateXPath = util.evaluateXPath; this.pageInfo = {}; diff --git a/common/content/commandline.js b/common/content/commandline.js index 1c0647bb..18865e97 100644 --- a/common/content/commandline.js +++ b/common/content/commandline.js @@ -8,7 +8,7 @@ /** @scope modules */ -const CommandWidgets = Class("CommandWidgets", { +var CommandWidgets = Class("CommandWidgets", { init: function () { this.elements = {}; this.addElement({ @@ -200,7 +200,7 @@ const CommandWidgets = Class("CommandWidgets", { * It consists of a prompt and command field be sure to only create objects of * this class when the chrome is ready. */ -const CommandLine = Module("commandline", { +var CommandLine = Module("commandline", { init: function () { const self = this; @@ -1766,7 +1766,7 @@ const CommandLine = Module("commandline", { * must be in its own container element, whose height it will update as * necessary. */ -const ItemList = Class("ItemList", { +var ItemList = Class("ItemList", { init: function (id) { this._completionElements = []; diff --git a/common/content/commands.js b/common/content/commands.js index c508757d..b650f464 100644 --- a/common/content/commands.js +++ b/common/content/commands.js @@ -35,12 +35,12 @@ * @property {string} description A description of the option */ -const CommandOption = Struct("names", "type", "validator", "completer", "multiple", "description", "default"); +var CommandOption = Struct("names", "type", "validator", "completer", "multiple", "description", "default"); CommandOption.defaultValue("description", function () ""); CommandOption.defaultValue("type", function () CommandOption.NOARG); CommandOption.defaultValue("multiple", function () false); -const ArgType = Struct("description", "parse"); +var ArgType = Struct("description", "parse"); update(CommandOption, { /** * @property {object} The option argument is unspecified. Any argument @@ -108,7 +108,7 @@ update(CommandOption, { * @optional * @private */ -const Command = Class("Command", { +var Command = Class("Command", { init: function (specs, description, action, extraInfo) { specs = Array.concat(specs); // XXX let parsedSpecs = Command.parseSpecs(specs); @@ -377,7 +377,7 @@ const Command = Class("Command", { }); // Prototype. -const ex = { +var ex = { _args: function (cmd, args) { args = Array.slice(args); @@ -427,7 +427,7 @@ const ex = { /** * @instance commands */ -const Commands = Module("commands", { +var Commands = Module("commands", { init: function () { this._exCommands = []; this._exMap = {}; diff --git a/common/content/completion.js b/common/content/completion.js index c58c604f..cc9d6bf1 100644 --- a/common/content/completion.js +++ b/common/content/completion.js @@ -26,7 +26,7 @@ * @author Kris Maglione * @constructor */ -const CompletionContext = Class("CompletionContext", { +var CompletionContext = Class("CompletionContext", { init: function (editor, name, offset) { if (!name) name = ""; @@ -825,7 +825,7 @@ const CompletionContext = Class("CompletionContext", { /** * @instance completion */ -const Completion = Module("completion", { +var Completion = Module("completion", { init: function () { }, diff --git a/common/content/configbase.js b/common/content/configbase.js index e9e9800d..b068dac7 100644 --- a/common/content/configbase.js +++ b/common/content/configbase.js @@ -6,7 +6,7 @@ // given in the LICENSE.txt file included with this file. "use strict"; -const ConfigBase = Class(ModuleBase, { +var ConfigBase = Class(ModuleBase, { /** * Called on dactyl startup to allow for any arbitrary application-specific * initialization code. Must call superclass's init function. diff --git a/common/content/dactyl.js b/common/content/dactyl.js index dda0c8d8..ca2e011a 100644 --- a/common/content/dactyl.js +++ b/common/content/dactyl.js @@ -12,14 +12,14 @@ default xml namespace = XHTML; XML.ignoreWhitespace = false; XML.prettyPrinting = false; -const plugins = { __proto__: modules }; -const userContext = newContext(modules); +var plugins = { __proto__: modules }; +var userContext = newContext(modules); -const EVAL_ERROR = "__dactyl_eval_error"; -const EVAL_RESULT = "__dactyl_eval_result"; -const EVAL_STRING = "__dactyl_eval_string"; +var EVAL_ERROR = "__dactyl_eval_error"; +var EVAL_RESULT = "__dactyl_eval_result"; +var EVAL_STRING = "__dactyl_eval_string"; -const Dactyl = Module("dactyl", { +var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { init: function () { window.dactyl = this; // cheap attempt at compatibility diff --git a/common/content/editor.js b/common/content/editor.js index 5945f4fb..b6730218 100644 --- a/common/content/editor.js +++ b/common/content/editor.js @@ -10,7 +10,7 @@ // http://developer.mozilla.org/en/docs/Editor_Embedding_Guide /** @instance editor */ -const Editor = Module("editor", { +var Editor = Module("editor", { get isCaret() modes.getStack(1).main == modes.CARET, get isTextEdit() modes.getStack(1).main == modes.TEXT_EDIT, diff --git a/common/content/events.js b/common/content/events.js index 6b6b5c75..b9c4f5c7 100644 --- a/common/content/events.js +++ b/common/content/events.js @@ -11,7 +11,7 @@ /** * @instance events */ -const Events = Module("events", { +var Events = Module("events", { init: function () { this._fullscreen = window.fullScreen; this._lastFocus = null; diff --git a/common/content/finder.js b/common/content/finder.js index 91a671da..26c093e2 100644 --- a/common/content/finder.js +++ b/common/content/finder.js @@ -7,7 +7,7 @@ /** @scope modules */ /** @instance rangefinder */ -const RangeFinder = Module("rangefinder", { +var RangeFinder = Module("rangefinder", { init: function () { this.lastFindPattern = ""; }, @@ -251,7 +251,7 @@ const RangeFinder = Module("rangefinder", { * documents, and represents a major detriment to productivity where * large amounts of data are concerned (e.g., for API documents). */ -const RangeFind = Class("RangeFind", { +var RangeFind = Class("RangeFind", { init: function (matchCase, backward, elementPath, regexp) { this.window = Cu.getWeakReference(window); this.baseDocument = Cu.getWeakReference(content.document); diff --git a/common/content/hints.js b/common/content/hints.js index 61140e30..2785b09d 100644 --- a/common/content/hints.js +++ b/common/content/hints.js @@ -9,7 +9,7 @@ /** @scope modules */ /** @instance hints */ -const Hints = Module("hints", { +var Hints = Module("hints", { init: function init() { const self = this; diff --git a/common/content/history.js b/common/content/history.js index 1d8e791c..1e648fd6 100644 --- a/common/content/history.js +++ b/common/content/history.js @@ -6,7 +6,7 @@ // given in the LICENSE.txt file included with this file. "use strict"; -const History = Module("history", { +var History = Module("history", { get format() bookmarks.format, get service() services.history, diff --git a/common/content/io.js b/common/content/io.js index 29731ead..0f923b28 100644 --- a/common/content/io.js +++ b/common/content/io.js @@ -38,7 +38,7 @@ function Script(file) { * Provides a basic interface to common system I/O operations. * @instance io */ -const IO = Module("io", { +var IO = Module("io", { init: function () { this._processDir = services.directory.get("CurWorkD", Ci.nsIFile); this._cwd = this._processDir.path; diff --git a/common/content/javascript.js b/common/content/javascript.js index b29989bd..9325aa91 100644 --- a/common/content/javascript.js +++ b/common/content/javascript.js @@ -6,7 +6,7 @@ // TODO: Clean this up. -const JavaScript = Module("javascript", { +var JavaScript = Module("javascript", { init: function () { this._stack = []; this._functions = []; diff --git a/common/content/mappings.js b/common/content/mappings.js index d9281d88..d3a2a25d 100644 --- a/common/content/mappings.js +++ b/common/content/mappings.js @@ -29,7 +29,7 @@ * @optional * @private */ -const Map = Class("Map", { +var Map = Class("Map", { init: function (modes, keys, description, action, extraInfo) { modes = Array.concat(modes).map(function (m) isObject(m) ? m.mask : m); if (!modes.every(util.identity)) @@ -127,7 +127,7 @@ const Map = Class("Map", { /** * @instance mappings */ -const Mappings = Module("mappings", { +var Mappings = Module("mappings", { init: function () { this._main = []; // default mappings this._user = []; // user created mappings diff --git a/common/content/marks.js b/common/content/marks.js index c1a515b7..93e5221c 100644 --- a/common/content/marks.js +++ b/common/content/marks.js @@ -10,7 +10,7 @@ * @scope modules * @instance marks */ -const Marks = Module("marks", { +var Marks = Module("marks", { init: function init() { function replacer(key, val) val instanceof Ci.nsISupports ? null : val; this._localMarks = storage.newMap("local-marks", { privateData: true, replacer: replacer, store: true }); diff --git a/common/content/modes.js b/common/content/modes.js index bde52ba6..aab3b314 100644 --- a/common/content/modes.js +++ b/common/content/modes.js @@ -8,7 +8,7 @@ /** @scope modules */ -const Modes = Module("modes", { +var Modes = Module("modes", { init: function () { this.modeChars = {}; this._main = 1; // NORMAL diff --git a/common/content/modules.js b/common/content/modules.js index a1ed1640..df15743b 100644 --- a/common/content/modules.js +++ b/common/content/modules.js @@ -8,7 +8,7 @@ * @class ModuleBase * The base class for all modules. */ -const ModuleBase = Class("ModuleBase", { +var ModuleBase = Class("ModuleBase", { /** * @property {[string]} A list of module prerequisites which * must be initialized before this module is loaded. diff --git a/common/content/options.js b/common/content/options.js index 1f06f7e0..3df9e724 100644 --- a/common/content/options.js +++ b/common/content/options.js @@ -34,7 +34,7 @@ let ValueError = Class("ValueError", ErrorBase); * @optional * @private */ -const Option = Class("Option", { +var Option = Class("Option", { init: function (names, description, type, defaultValue, extraInfo) { this.name = names[0]; this.names = names; @@ -618,7 +618,7 @@ const Option = Class("Option", { /** * @instance options */ -const Options = Module("options", { +var Options = Module("options", { init: function () { this.needInit = []; this._options = []; diff --git a/common/content/quickmarks.js b/common/content/quickmarks.js index d41a6719..47ca77f0 100644 --- a/common/content/quickmarks.js +++ b/common/content/quickmarks.js @@ -11,7 +11,7 @@ /** * @instance quickmarks */ -const QuickMarks = Module("quickmarks", { +var QuickMarks = Module("quickmarks", { init: function () { this._qmarks = storage.newMap("quickmarks", { store: true }); storage.addObserver("quickmarks", function () { diff --git a/common/content/statusline.js b/common/content/statusline.js index 7914744c..07695b44 100644 --- a/common/content/statusline.js +++ b/common/content/statusline.js @@ -8,7 +8,7 @@ /** @scope modules */ -const StatusLine = Module("statusline", { +var StatusLine = Module("statusline", { init: function () { this._statusLine = document.getElementById("status-bar"); this.statusBar = document.getElementById("addon-bar") || this._statusLine; diff --git a/common/content/tabs.js b/common/content/tabs.js index 5337abc9..f7a6ad5f 100644 --- a/common/content/tabs.js +++ b/common/content/tabs.js @@ -13,7 +13,7 @@ /** * @instance tabs */ -const Tabs = Module("tabs", { +var Tabs = Module("tabs", { init: function () { this._alternates = [config.tabbrowser.mCurrentTab, null]; diff --git a/common/modules/base.jsm b/common/modules/base.jsm index 7de7cb39..765247f4 100644 --- a/common/modules/base.jsm +++ b/common/modules/base.jsm @@ -13,19 +13,19 @@ if (!JSMLoader) dump("dactyl: load: " + url + "\n"); if (this.stale[url]) { delete this.stale[url]; - dump("dactyl: load stale\n"); - let global = this.globals[url]; + for each (let prop in Object.getOwnPropertyNames(global)) try { - if (!set.has(this.builtin, prop) && [this, set].indexOf(global[prop]) < 0) + if (!set.has(this.builtin, prop) && + [this, set].indexOf(Object.getOwnPropertyDescriptor(global, prop).value) < 0) delete global[prop]; } catch (e) {} Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader) - .loadSubScript(url, this.globals[url]); + .loadSubScript(url, global); dump("dactyl: load reloaded: " + url + "\n"); } Components.utils.import(url, target); @@ -859,10 +859,10 @@ Class.prototype = { */ timeout: function (callback, timeout) { const self = this; - let notify = { notify: function notify(timer) { try { callback.apply(self); } catch (e) { util.reportError(e); } } }; - let timer = services.Timer(); - timer.initWithCallback(notify, timeout || 0, timer.TYPE_ONE_SHOT); - return timer; + function notify(timer) { + util.trapErrors(callback, self); + } + return services.Timer(notify, timeout || 0, services.Timer.TYPE_ONE_SHOT);; } }; memoize(Class.prototype, "closure", function () { diff --git a/common/modules/util.jsm b/common/modules/util.jsm index ac8410e5..0fcdc920 100644 --- a/common/modules/util.jsm +++ b/common/modules/util.jsm @@ -23,7 +23,7 @@ default xml namespace = XHTML; memoize(this, "Commands", function () { // FIXME - let obj = {}; + let obj = { Module: Class }; services.subscriptLoader.loadSubScript("chrome://dactyl/content/commands.js", obj); return obj.Commands; }); @@ -94,20 +94,28 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), addObserver: function (obj) { let observers = obj._observe || obj.observe; obj._observe = observers; + function register(meth) { - services.observer[meth](obj, "quit-application", true); - services.observer[meth](obj, "dactyl-cleanup", true); - for (let target in keys(observers)) - services.observer[meth](obj, target, true); + for (let target in set(["dactyl-cleanup", "quit-application"].concat(Object.keys(observers)))) + try { + services.observer[meth](obj, target, true); + } + catch (e) {} } Class.replaceProperty(obj, "observe", function (subject, target, data) { - if (target == "quit-application" || target == "dactyl-cleanup") - register("removeObserver"); - if (observers[target]) - observers[target].call(obj, subject, data); + try { + if (target == "quit-application" || target == "dactyl-cleanup") + register("removeObserver"); + if (observers[target]) + observers[target].call(obj, subject, data); + } + catch (e) { + util.reportError(e); + } }); - obj.observe.unRegister = function () register("removeObserver"); + + obj.observe.unregister = function () register("removeObserver"); register("addObserver"); }, @@ -457,6 +465,14 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), */ dump: defineModule.dump, + stackLines: function (stack) { + let lines = []; + let match, re = /([^]*?)(@.*?)(?:\n|$)/g; + while (match = re.exec(stack)) + lines.push(match[1].replace(/\n/g, "\\n").substr(0, 80) + match[2]); + return lines; + }, + /** * Dumps a stack trace to the console. * @@ -464,9 +480,8 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), * @param {number} frames The number of frames to print. */ dumpStack: function dumpStack(msg, frames) { - let stack = Error().stack.replace(/(?:.*\n){2}/, ""); - if (frames != null) - [stack] = stack.match(RegExp("(?:.*\n){0," + frames + "}")); + let stack = util.stackLines(Error().stack); + stack = stack.slice(2, 2 + (frames || 0)).join("\n"); util.dump((arguments.length == 0 ? "Stack" : msg) + "\n" + stack + "\n"); }, @@ -1126,7 +1141,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), try { let obj = update({}, error, { toString: function () String(error), - stack: <>{String.replace(error.stack || Error().stack, /^/mg, "\t")} + stack: <>{util.stackLines(String(error.stack || Error().stack)).join("\n").replace(/^/mg, "\t")} }); this.errors.push([new Date, obj + "\n" + obj.stack]); @@ -1140,7 +1155,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), catch (e) { try { this.dump(String(error)); - this.dump(error.stack) + this.dump(util.stackLines(error.stack).join("\n")) } catch (e) { dump(e + "\n"); } }