1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-30 23:52:27 +01:00

Use evalInSandbox for :js rather than the subscript loader so that we can preserve file names/line numbers.

This commit is contained in:
Kris Maglione
2010-10-04 21:33:39 -04:00
parent a21c2510e3
commit 2012279ad9
10 changed files with 46 additions and 53 deletions

View File

@@ -105,7 +105,7 @@ const ConfigBase = Class(ModuleBase, {
/** /**
* @property {string} The ID of the application's main XUL window. * @property {string} The ID of the application's main XUL window.
*/ */
mainWindowId: document.documentElement.id, mainWindowId: window.document.documentElement.id,
/** /**
* @property {[[]]} An array of application specific mode specifications. * @property {[[]]} An array of application specific mode specifications.
@@ -133,7 +133,7 @@ const ConfigBase = Class(ModuleBase, {
*/ */
scripts: [], scripts: [],
tabStrip: Class.memoize(function () document.getElementById("TabsToolbar") || this.tabbrowser.mTabContainer), tabStrip: Class.memoize(function () window.document.getElementById("TabsToolbar") || this.tabbrowser.mTabContainer),
/** /**
* @property {string} The leaf name of any temp files created by * @property {string} The leaf name of any temp files created by

View File

@@ -5,12 +5,21 @@
"use strict"; "use strict";
(function () { (function () {
const jsmodules = {} function newContext(proto) {
const modules = { __proto__: jsmodules }; let sandbox = Components.utils.Sandbox(window);
const BASE = "chrome://dactyl/content/"; if (jsmodules.__proto__ != window)
jsmodules.__proto__ = window;
// Hack:
sandbox.Object = jsmodules.Object;
sandbox.Math = jsmodules.Math;
sandbox.__proto__ = proto || modules;
return sandbox;
}
const jsmodules = {};
const modules = { __proto__: jsmodules, jsmodules: jsmodules, newContext: newContext, window: window };
modules.modules = modules; modules.modules = modules;
const BASE = "chrome://dactyl/content/";
const loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] const loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader); .getService(Components.interfaces.mozIJSSubScriptLoader);

View File

@@ -13,7 +13,7 @@ XML.ignoreWhitespace = false;
XML.prettyPrinting = false; XML.prettyPrinting = false;
const plugins = { __proto__: modules }; const plugins = { __proto__: modules };
const userContext = { __proto__: modules }; memoize(modules, "userContext", function () newContext(modules));;
const EVAL_ERROR = "__dactyl_eval_error"; const EVAL_ERROR = "__dactyl_eval_error";
const EVAL_RESULT = "__dactyl_eval_result"; const EVAL_RESULT = "__dactyl_eval_result";
@@ -314,29 +314,16 @@ const Dactyl = Module("dactyl", {
services.get("subscriptLoader").loadSubScript(uri, context, File.defaultEncoding); services.get("subscriptLoader").loadSubScript(uri, context, File.defaultEncoding);
}, },
userEval: function (str, context) { userEval: function (str, context, fileName, lineNumber) {
try { if (fileName == null)
if (!context) if (io.sourcing)
context = userContext; ({ file: fileName, line: lineNumber }) = io.sourcing;
context[EVAL_ERROR] = null; else if (String.indexOf(commandline.command, str) > -1)
context[EVAL_STRING] = str; [fileName, lineNumber] = ["[Command Line]", 1];
context[EVAL_RESULT] = null;
this.loadScript("chrome://dactyl/content/eval.js", context); if (!context)
if (context[EVAL_ERROR]) { context = userContext;
try { return Cu.evalInSandbox(str, context, "1.8", fileName, lineNumber);
context[EVAL_ERROR].fileName = io.sourcing.file;
context[EVAL_ERROR].lineNumber += io.sourcing.line;
}
catch (e) {}
throw context[EVAL_ERROR];
}
return context[EVAL_RESULT];
}
finally {
delete context[EVAL_ERROR];
delete context[EVAL_RESULT];
delete context[EVAL_STRING];
}
}, },
/** /**
@@ -885,11 +872,7 @@ const Dactyl = Module("dactyl", {
pluginFiles: {}, pluginFiles: {},
// namespace for plugins/scripts. Actually (only) the active plugin must/can set a get plugins() plugins,
// v.plugins.mode = <str> string to show on v.modes.CUSTOM
// v.plugins.stop = <func> hooked on a v.modes.reset()
// v.plugins.onEvent = <func> function triggered, on keypresses (unless <esc>) (see events.js)
plugins: plugins,
/** /**
* Quit the host application, no matter how many tabs/windows are open. * Quit the host application, no matter how many tabs/windows are open.

View File

@@ -731,7 +731,7 @@ const Events = Module("events", {
let win = window.document.commandDispatcher.focusedWindow; let win = window.document.commandDispatcher.focusedWindow;
let elem = window.document.commandDispatcher.focusedElement; let elem = window.document.commandDispatcher.focusedElement;
if (win && win.top == content && dactyl.has("tabs")) if (win && win.top == window.content && dactyl.has("tabs"))
buffer.focusedFrame = win; buffer.focusedFrame = win;
try { try {

View File

@@ -9,7 +9,7 @@
/** @scope modules */ /** @scope modules */
plugins.contexts = {}; plugins.contexts = plugins;
function Script(file) { function Script(file) {
let self = plugins[file.path]; let self = plugins[file.path];
if (self) { if (self) {
@@ -19,11 +19,10 @@ function Script(file) {
} }
else else
self = { __proto__: plugins }; self = { __proto__: plugins };
plugins.contexts[file.path] = self;
plugins[file.path] = self; plugins[file.path] = self;
self.NAME = file.leafName.replace(/\..*/, "").replace(/-([a-z])/g, function (m, n1) n1.toUpperCase()); self.NAME = file.leafName.replace(/\..*/, "").replace(/-([a-z])/g, function (m, n1) n1.toUpperCase());
self.PATH = file.path; self.PATH = file.path;
self.__context__ = self; self.CONTEXT = self;
// This belongs elsewhere // This belongs elsewhere
if (io.getRuntimeDirectories("plugins").some( if (io.getRuntimeDirectories("plugins").some(
@@ -366,6 +365,7 @@ lookup:
this.readHeredoc = function (end) { this.readHeredoc = function (end) {
let res = []; let res = [];
try { try {
io.sourcing.line++;
while (true) while (true)
let ([i, line] = iter.next()) { let ([i, line] = iter.next()) {
if (line === end) if (line === end)

View File

@@ -38,12 +38,12 @@ const JavaScript = Module("javascript", {
if (obj == null) if (obj == null)
return; return;
let seen = {}; let seen = isinstance(obj, ["Sandbox"]) ? set(JavaScript.magicalNames) : {};
let globals = values(toplevel && Class.objectGlobal(obj) === obj ? JavaScript.globalNames : []); let globals = values(toplevel && window === obj ? JavaScript.globalNames : []);
for (let key in iterAll(globals, properties(obj, !toplevel))) { for (let key in iterAll(globals, properties(obj, !toplevel)))
set.add(seen, key); if (!set.add(seen, key))
yield key; yield key;
}
// Properties aren't visible in an XPCNativeWrapper until // Properties aren't visible in an XPCNativeWrapper until
// they're accessed. // they're accessed.
for (let key in properties(this.getKey(obj, "wrappedJSObject"), !toplevel)) for (let key in properties(this.getKey(obj, "wrappedJSObject"), !toplevel))
@@ -58,7 +58,7 @@ const JavaScript = Module("javascript", {
// Things we can dereference // Things we can dereference
if (!obj || ["object", "string", "function"].indexOf(typeof obj) == -1) if (!obj || ["object", "string", "function"].indexOf(typeof obj) == -1)
return []; return [];
if (modules.isPrototypeOf(obj) && !toplevel) if (jsmodules.isPrototypeOf(obj) && !toplevel)
return []; return [];
let completions = [k for (k in this.iter(obj, toplevel))]; let completions = [k for (k in this.iter(obj, toplevel))];
@@ -76,7 +76,7 @@ const JavaScript = Module("javascript", {
context[JavaScript.EVAL_TMP] = tmp; context[JavaScript.EVAL_TMP] = tmp;
try { try {
return cache[key] = dactyl.userEval(arg, context); return cache[key] = dactyl.userEval(arg, context, "[Command Line Completion]", 1);
} }
catch (e) { catch (e) {
this.context.message = "Error: " + e; this.context.message = "Error: " + e;
@@ -308,7 +308,7 @@ const JavaScript = Module("javascript", {
context.filters.push(function (item) item.item.indexOf(args.prefix) === 0); context.filters.push(function (item) item.item.indexOf(args.prefix) === 0);
} }
args.completer.call(self, context, args); args.completer.call(this, context, args);
}, },
_complete: function (objects, key, compl, string, last) { _complete: function (objects, key, compl, string, last) {
@@ -428,7 +428,7 @@ const JavaScript = Module("javascript", {
} }
this.context.getCache("evalled", Object); this.context.getCache("evalled", Object);
this.context.getCache("evalContext", function () ({ __proto__: userContext })); this.context.getCache("evalContext", function () newContext(userContext));
// Okay, have parse stack. Figure out what we're completing. // Okay, have parse stack. Figure out what we're completing.
@@ -594,6 +594,8 @@ const JavaScript = Module("javascript", {
*/ */
completers: {}, completers: {},
magicalNames: Class.memoize(function () Object.getOwnPropertyNames(Cu.Sandbox(window), true).sort()),
/** /**
* A list of properties of the global object which are not * A list of properties of the global object which are not
* enumerable by any standard method. * enumerable by any standard method.
@@ -616,6 +618,7 @@ const JavaScript = Module("javascript", {
"isXMLName", "parseFloat", "parseInt", "undefined", "uneval" "isXMLName", "parseFloat", "parseInt", "undefined", "uneval"
].concat([k.substr(6) for (k in keys(Ci)) if (/^nsIDOM/.test(k))]) ].concat([k.substr(6) for (k in keys(Ci)) if (/^nsIDOM/.test(k))])
.concat([k.substr(3) for (k in keys(Ci)) if (/^nsI/.test(k))]) .concat([k.substr(3) for (k in keys(Ci)) if (/^nsI/.test(k))])
.concat(JavaScript.magicalnames)
.filter(function (k) k in window))), .filter(function (k) k in window))),
/** /**

View File

@@ -403,7 +403,6 @@ want to bypass &dactyl.appName;'s key handling and pass keys directly to
<item> <item>
<tags>:w :write :sav :saveas</tags> <tags>:w :write :sav :saveas</tags>
<strut/>
<spec>:sav<oa>eas</oa><oa>!</oa> <oa>file</oa></spec> <spec>:sav<oa>eas</oa><oa>!</oa> <oa>file</oa></spec>
<description> <description>
<p> <p>

View File

@@ -66,7 +66,7 @@ if (!Object.getOwnPropertyDescriptor)
return desc; return desc;
}; };
if (!Object.getOwnPropertyNames) if (!Object.getOwnPropertyNames)
Object.getOwnPropertyNames = function getOwnPropertyNames(obj) { Object.getOwnPropertyNames = function getOwnPropertyNames(obj, _debugger) {
// This is an ugly and unfortunately necessary hack. // This is an ugly and unfortunately necessary hack.
if (hasOwnProperty.call(obj, "__iterator__")) { if (hasOwnProperty.call(obj, "__iterator__")) {
var oldIter = obj.__iterator__; var oldIter = obj.__iterator__;

View File

@@ -124,7 +124,7 @@ const Services = Module("Services", {
}, { }, {
}, { }, {
init: function (dactyl, modules) { init: function (dactyl, modules) {
if (!this.get("extensionManager")) if (!modules.AddonManager && !this.get("extensionManager"))
Components.utils.import("resource://gre/modules/AddonManager.jsm", modules); Components.utils.import("resource://gre/modules/AddonManager.jsm", modules);
}, },
javascript: function (dactyl, modules) { javascript: function (dactyl, modules) {

View File

@@ -39,7 +39,6 @@ FEATURES:
8 <C-o>/<C-i> should work as in vim (i.e., save page positions as well as 8 <C-o>/<C-i> should work as in vim (i.e., save page positions as well as
locations in the history list). locations in the history list).
8 jump to the next heading with ]h, next image ]i, previous textbox [t and so on 8 jump to the next heading with ]h, next image ]i, previous textbox [t and so on
8 pipe selected text/link/website to an external command
7 use ctrl-n/p in insert mode for word completion 7 use ctrl-n/p in insert mode for word completion
7 implement QuickFix window based on ItemList 7 implement QuickFix window based on ItemList
7 wherever possible: get rid of dialogs and ask console-like dialog questions 7 wherever possible: get rid of dialogs and ask console-like dialog questions