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:
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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))),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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__;
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user