mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2026-01-03 09:44:13 +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.
|
||||
*/
|
||||
mainWindowId: document.documentElement.id,
|
||||
mainWindowId: window.document.documentElement.id,
|
||||
|
||||
/**
|
||||
* @property {[[]]} An array of application specific mode specifications.
|
||||
@@ -133,7 +133,7 @@ const ConfigBase = Class(ModuleBase, {
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -5,12 +5,21 @@
|
||||
"use strict";
|
||||
|
||||
(function () {
|
||||
const jsmodules = {}
|
||||
const modules = { __proto__: jsmodules };
|
||||
const BASE = "chrome://dactyl/content/";
|
||||
|
||||
function newContext(proto) {
|
||||
let sandbox = Components.utils.Sandbox(window);
|
||||
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;
|
||||
|
||||
const BASE = "chrome://dactyl/content/";
|
||||
const loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
|
||||
.getService(Components.interfaces.mozIJSSubScriptLoader);
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ XML.ignoreWhitespace = false;
|
||||
XML.prettyPrinting = false;
|
||||
|
||||
const plugins = { __proto__: modules };
|
||||
const userContext = { __proto__: modules };
|
||||
memoize(modules, "userContext", function () newContext(modules));;
|
||||
|
||||
const EVAL_ERROR = "__dactyl_eval_error";
|
||||
const EVAL_RESULT = "__dactyl_eval_result";
|
||||
@@ -314,29 +314,16 @@ const Dactyl = Module("dactyl", {
|
||||
services.get("subscriptLoader").loadSubScript(uri, context, File.defaultEncoding);
|
||||
},
|
||||
|
||||
userEval: function (str, context) {
|
||||
try {
|
||||
if (!context)
|
||||
context = userContext;
|
||||
context[EVAL_ERROR] = null;
|
||||
context[EVAL_STRING] = str;
|
||||
context[EVAL_RESULT] = null;
|
||||
this.loadScript("chrome://dactyl/content/eval.js", context);
|
||||
if (context[EVAL_ERROR]) {
|
||||
try {
|
||||
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];
|
||||
}
|
||||
userEval: function (str, context, fileName, lineNumber) {
|
||||
if (fileName == null)
|
||||
if (io.sourcing)
|
||||
({ file: fileName, line: lineNumber }) = io.sourcing;
|
||||
else if (String.indexOf(commandline.command, str) > -1)
|
||||
[fileName, lineNumber] = ["[Command Line]", 1];
|
||||
|
||||
if (!context)
|
||||
context = userContext;
|
||||
return Cu.evalInSandbox(str, context, "1.8", fileName, lineNumber);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -885,11 +872,7 @@ const Dactyl = Module("dactyl", {
|
||||
|
||||
pluginFiles: {},
|
||||
|
||||
// namespace for plugins/scripts. Actually (only) the active plugin must/can set a
|
||||
// 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,
|
||||
get plugins() plugins,
|
||||
|
||||
/**
|
||||
* 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 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;
|
||||
|
||||
try {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
/** @scope modules */
|
||||
|
||||
plugins.contexts = {};
|
||||
plugins.contexts = plugins;
|
||||
function Script(file) {
|
||||
let self = plugins[file.path];
|
||||
if (self) {
|
||||
@@ -19,11 +19,10 @@ function Script(file) {
|
||||
}
|
||||
else
|
||||
self = { __proto__: plugins };
|
||||
plugins.contexts[file.path] = self;
|
||||
plugins[file.path] = self;
|
||||
self.NAME = file.leafName.replace(/\..*/, "").replace(/-([a-z])/g, function (m, n1) n1.toUpperCase());
|
||||
self.PATH = file.path;
|
||||
self.__context__ = self;
|
||||
self.CONTEXT = self;
|
||||
|
||||
// This belongs elsewhere
|
||||
if (io.getRuntimeDirectories("plugins").some(
|
||||
@@ -366,6 +365,7 @@ lookup:
|
||||
this.readHeredoc = function (end) {
|
||||
let res = [];
|
||||
try {
|
||||
io.sourcing.line++;
|
||||
while (true)
|
||||
let ([i, line] = iter.next()) {
|
||||
if (line === end)
|
||||
|
||||
@@ -38,12 +38,12 @@ const JavaScript = Module("javascript", {
|
||||
if (obj == null)
|
||||
return;
|
||||
|
||||
let seen = {};
|
||||
let globals = values(toplevel && Class.objectGlobal(obj) === obj ? JavaScript.globalNames : []);
|
||||
for (let key in iterAll(globals, properties(obj, !toplevel))) {
|
||||
set.add(seen, key);
|
||||
yield key;
|
||||
}
|
||||
let seen = isinstance(obj, ["Sandbox"]) ? set(JavaScript.magicalNames) : {};
|
||||
let globals = values(toplevel && window === obj ? JavaScript.globalNames : []);
|
||||
for (let key in iterAll(globals, properties(obj, !toplevel)))
|
||||
if (!set.add(seen, key))
|
||||
yield key;
|
||||
|
||||
// Properties aren't visible in an XPCNativeWrapper until
|
||||
// they're accessed.
|
||||
for (let key in properties(this.getKey(obj, "wrappedJSObject"), !toplevel))
|
||||
@@ -58,7 +58,7 @@ const JavaScript = Module("javascript", {
|
||||
// Things we can dereference
|
||||
if (!obj || ["object", "string", "function"].indexOf(typeof obj) == -1)
|
||||
return [];
|
||||
if (modules.isPrototypeOf(obj) && !toplevel)
|
||||
if (jsmodules.isPrototypeOf(obj) && !toplevel)
|
||||
return [];
|
||||
|
||||
let completions = [k for (k in this.iter(obj, toplevel))];
|
||||
@@ -76,7 +76,7 @@ const JavaScript = Module("javascript", {
|
||||
|
||||
context[JavaScript.EVAL_TMP] = tmp;
|
||||
try {
|
||||
return cache[key] = dactyl.userEval(arg, context);
|
||||
return cache[key] = dactyl.userEval(arg, context, "[Command Line Completion]", 1);
|
||||
}
|
||||
catch (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);
|
||||
}
|
||||
|
||||
args.completer.call(self, context, args);
|
||||
args.completer.call(this, context, args);
|
||||
},
|
||||
|
||||
_complete: function (objects, key, compl, string, last) {
|
||||
@@ -428,7 +428,7 @@ const JavaScript = Module("javascript", {
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
@@ -594,6 +594,8 @@ const JavaScript = Module("javascript", {
|
||||
*/
|
||||
completers: {},
|
||||
|
||||
magicalNames: Class.memoize(function () Object.getOwnPropertyNames(Cu.Sandbox(window), true).sort()),
|
||||
|
||||
/**
|
||||
* A list of properties of the global object which are not
|
||||
* enumerable by any standard method.
|
||||
@@ -616,6 +618,7 @@ const JavaScript = Module("javascript", {
|
||||
"isXMLName", "parseFloat", "parseInt", "undefined", "uneval"
|
||||
].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(JavaScript.magicalnames)
|
||||
.filter(function (k) k in window))),
|
||||
|
||||
/**
|
||||
|
||||
@@ -403,7 +403,6 @@ want to bypass &dactyl.appName;'s key handling and pass keys directly to
|
||||
|
||||
<item>
|
||||
<tags>:w :write :sav :saveas</tags>
|
||||
<strut/>
|
||||
<spec>:sav<oa>eas</oa><oa>!</oa> <oa>file</oa></spec>
|
||||
<description>
|
||||
<p>
|
||||
|
||||
@@ -66,7 +66,7 @@ if (!Object.getOwnPropertyDescriptor)
|
||||
return desc;
|
||||
};
|
||||
if (!Object.getOwnPropertyNames)
|
||||
Object.getOwnPropertyNames = function getOwnPropertyNames(obj) {
|
||||
Object.getOwnPropertyNames = function getOwnPropertyNames(obj, _debugger) {
|
||||
// This is an ugly and unfortunately necessary hack.
|
||||
if (hasOwnProperty.call(obj, "__iterator__")) {
|
||||
var oldIter = obj.__iterator__;
|
||||
|
||||
@@ -124,7 +124,7 @@ const Services = Module("Services", {
|
||||
}, {
|
||||
}, {
|
||||
init: function (dactyl, modules) {
|
||||
if (!this.get("extensionManager"))
|
||||
if (!modules.AddonManager && !this.get("extensionManager"))
|
||||
Components.utils.import("resource://gre/modules/AddonManager.jsm", 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
|
||||
locations in the history list).
|
||||
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 implement QuickFix window based on ItemList
|
||||
7 wherever possible: get rid of dialogs and ask console-like dialog questions
|
||||
|
||||
Reference in New Issue
Block a user