mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-20 06:07:59 +01:00
Do something remotely reasonable where designMode documents are concerned. Some fixes for evalInSandbox problems in recent nightlies.
This commit is contained in:
@@ -444,7 +444,7 @@ const Buffer = Module("buffer", {
|
|||||||
*/
|
*/
|
||||||
get focusedFrame() {
|
get focusedFrame() {
|
||||||
let frame = (dactyl.has("tabs") ? tabs.localStore : this.localStore).focusedFrame;
|
let frame = (dactyl.has("tabs") ? tabs.localStore : this.localStore).focusedFrame;
|
||||||
return frame && frame.get();
|
return frame && frame.get() || content;
|
||||||
},
|
},
|
||||||
set focusedFrame(frame) {
|
set focusedFrame(frame) {
|
||||||
(dactyl.has("tabs") ? tabs.localStore : this.localStore).focusedFrame = Cu.getWeakReference(frame);
|
(dactyl.has("tabs") ? tabs.localStore : this.localStore).focusedFrame = Cu.getWeakReference(frame);
|
||||||
@@ -508,13 +508,19 @@ const Buffer = Module("buffer", {
|
|||||||
win.dactylFocusAllowed = true;
|
win.dactylFocusAllowed = true;
|
||||||
|
|
||||||
if (isinstance(elem, [HTMLFrameElement, HTMLIFrameElement]))
|
if (isinstance(elem, [HTMLFrameElement, HTMLIFrameElement]))
|
||||||
elem.contentWindow.focus();
|
elem = elem.contentWindow;
|
||||||
else if (elem instanceof HTMLInputElement && elem.type == "file") {
|
elem.dactylFocusAllowed = true;
|
||||||
|
|
||||||
|
if (elem instanceof HTMLInputElement && elem.type == "file") {
|
||||||
Buffer.openUploadPrompt(elem);
|
Buffer.openUploadPrompt(elem);
|
||||||
buffer.lastInputField = elem;
|
buffer.lastInputField = elem;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
elem.focus();
|
elem.focus();
|
||||||
|
if (elem instanceof Window && elem.getSelection() && !elem.getSelection().rangeCount)
|
||||||
|
elem.getSelection().addRange(RangeFind.endpoint(
|
||||||
|
RangeFind.nodeRange(elem.document.body || elem.document.documentElement),
|
||||||
|
true));
|
||||||
|
|
||||||
// for imagemap
|
// for imagemap
|
||||||
if (elem instanceof HTMLAreaElement) {
|
if (elem instanceof HTMLAreaElement) {
|
||||||
@@ -1618,12 +1624,14 @@ const Buffer = Module("buffer", {
|
|||||||
let elem = buffer.lastInputField;
|
let elem = buffer.lastInputField;
|
||||||
|
|
||||||
if (count >= 1 || !elem || !Events.isContentNode(elem)) {
|
if (count >= 1 || !elem || !Events.isContentNode(elem)) {
|
||||||
let xpath = ["input", "textarea[not(@disabled) and not(@readonly)]"];
|
let xpath = ["frame", "iframe", "input", "textarea[not(@disabled) and not(@readonly)]"];
|
||||||
|
|
||||||
let frames = buffer.allFrames(null, true);
|
let frames = buffer.allFrames(null, true);
|
||||||
|
|
||||||
let elements = array.flatten(frames.map(function (win) [m for (m in util.evaluateXPath(xpath, win.document))]))
|
let elements = array.flatten(frames.map(function (win) [m for (m in util.evaluateXPath(xpath, win.document))]))
|
||||||
.filter(function (elem) {
|
.filter(function (elem) {
|
||||||
|
if (isinstance(elem, [HTMLFrameElement, HTMLIFrameElement]))
|
||||||
|
return Editor.getEditor(elem.contentWindow);
|
||||||
|
|
||||||
if (elem.readOnly || elem instanceof HTMLInputElement && !set.has(util.editableInputs, elem.type))
|
if (elem.readOnly || elem instanceof HTMLInputElement && !set.has(util.editableInputs, elem.type))
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -257,15 +257,15 @@ const Command = Class("Command", {
|
|||||||
options: [],
|
options: [],
|
||||||
optionMap: Class.memoize(function () array(this.options)
|
optionMap: Class.memoize(function () array(this.options)
|
||||||
.map(function (opt) opt.names.map(function (name) [name, opt]))
|
.map(function (opt) opt.names.map(function (name) [name, opt]))
|
||||||
.flatten.toObject()),
|
.flatten().toObject()),
|
||||||
newArgs: function () {
|
newArgs: function () {
|
||||||
let res = [];
|
let res = [];
|
||||||
res.__proto__ = this.argsPrototype;
|
res.__proto__ = this.argsPrototype;
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
argsPrototype: Class.memoize(function () update([],
|
argsPrototype: Class.memoize(function () update([],
|
||||||
array([opt, opt.default] for (opt in values(this.options)) if (set.has(opt, "default")))
|
array(this.options).filter(function (opt) opt.default !== undefined)
|
||||||
.toObject(),
|
.map(function (opt) [opt.names[0], opt.default]).toObject(),
|
||||||
{
|
{
|
||||||
__iterator__: function () array.iterItems(this),
|
__iterator__: function () array.iterItems(this),
|
||||||
command: this,
|
command: this,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
function newContext(proto) {
|
function newContext(proto) {
|
||||||
let sandbox = Components.utils.Sandbox(window);
|
let sandbox = Components.utils.Sandbox(window, { sandboxPrototype: proto || modules, wantXrays: false });
|
||||||
// Hack:
|
// Hack:
|
||||||
sandbox.Object = jsmodules.Object;
|
sandbox.Object = jsmodules.Object;
|
||||||
sandbox.Math = jsmodules.Math;
|
sandbox.Math = jsmodules.Math;
|
||||||
|
|||||||
@@ -348,6 +348,7 @@ const Dactyl = Module("dactyl", {
|
|||||||
if (window != services.get("windowWatcher").activeWindow)
|
if (window != services.get("windowWatcher").activeWindow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
let win = document.commandDispatcher.focusedWindow;
|
||||||
let elem = config.mainWidget || window.content;
|
let elem = config.mainWidget || window.content;
|
||||||
// TODO: make more generic
|
// TODO: make more generic
|
||||||
try {
|
try {
|
||||||
@@ -357,16 +358,26 @@ const Dactyl = Module("dactyl", {
|
|||||||
i = 0;
|
i = 0;
|
||||||
gDBView.selection.select(i);
|
gDBView.selection.select(i);
|
||||||
}
|
}
|
||||||
else if (this.has("tabs")) {
|
else {
|
||||||
let frame = buffer.focusedFrame;
|
let frame = buffer.focusedFrame;
|
||||||
if (frame && frame.top == window.content)
|
if (frame && frame.top == window.content && !Editor.getEditor(frame))
|
||||||
elem = frame;
|
elem = frame;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e) {}
|
catch (e) {}
|
||||||
|
|
||||||
if (clearFocusedElement && dactyl.focus)
|
if (clearFocusedElement)
|
||||||
dactyl.focus.blur();
|
if (dactyl.focus)
|
||||||
|
dactyl.focus.blur();
|
||||||
|
else if (win) {
|
||||||
|
win.blur();
|
||||||
|
if (win.frameElement)
|
||||||
|
win.frameElement.blur();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elem instanceof Window && Editor.getEditor(elem))
|
||||||
|
elem = window;
|
||||||
|
|
||||||
if (elem && elem != dactyl.focus)
|
if (elem && elem != dactyl.focus)
|
||||||
elem.focus();
|
elem.focus();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -20,43 +20,14 @@ const Editor = Module("editor", {
|
|||||||
get isCaret() modes.getStack(1).main === modes.CARET,
|
get isCaret() modes.getStack(1).main === modes.CARET,
|
||||||
get isTextEdit() modes.getStack(1).main === modes.TEXT_EDIT,
|
get isTextEdit() modes.getStack(1).main === modes.TEXT_EDIT,
|
||||||
|
|
||||||
line: function () {
|
|
||||||
let line = 1;
|
|
||||||
let text = Editor.getEditor().value;
|
|
||||||
for (let i = 0; i < Editor.getEditor().selectionStart; i++)
|
|
||||||
if (text[i] == "\n")
|
|
||||||
line++;
|
|
||||||
return line;
|
|
||||||
},
|
|
||||||
|
|
||||||
col: function () {
|
|
||||||
let col = 1;
|
|
||||||
let text = Editor.getEditor().value;
|
|
||||||
for (let i = 0; i < Editor.getEditor().selectionStart; i++) {
|
|
||||||
col++;
|
|
||||||
if (text[i] == "\n")
|
|
||||||
col = 1;
|
|
||||||
}
|
|
||||||
return col;
|
|
||||||
},
|
|
||||||
|
|
||||||
unselectText: function (toEnd) {
|
unselectText: function (toEnd) {
|
||||||
let elem = dactyl.focus;
|
|
||||||
// A error occurs if the element has been removed when "elem.selectionStart" is executed.
|
|
||||||
try {
|
try {
|
||||||
if (elem && elem.selectionEnd)
|
Editor.getEditor(null).selection[toEnd ? "collapseToEnd" : "collapseToStart"]();
|
||||||
if (toEnd)
|
|
||||||
elem.selectionStart = elem.selectionEnd;
|
|
||||||
else
|
|
||||||
elem.selectionEnd = elem.selectionStart;
|
|
||||||
}
|
}
|
||||||
catch (e) {}
|
catch (e) {};
|
||||||
},
|
},
|
||||||
|
|
||||||
selectedText: function () {
|
selectedText: function () String(Editor.getEditor(null).selection),
|
||||||
let text = Editor.getEditor().value;
|
|
||||||
return text.substring(Editor.getEditor().selectionStart, Editor.getEditor().selectionEnd);
|
|
||||||
},
|
|
||||||
|
|
||||||
pasteClipboard: function (clipboard, toStart) {
|
pasteClipboard: function (clipboard, toStart) {
|
||||||
if (util.isOS("WINNT")) {
|
if (util.isOS("WINNT")) {
|
||||||
@@ -98,10 +69,9 @@ const Editor = Module("editor", {
|
|||||||
// count is optional, defaults to 1
|
// count is optional, defaults to 1
|
||||||
executeCommand: function (cmd, count) {
|
executeCommand: function (cmd, count) {
|
||||||
let controller = Editor.getController();
|
let controller = Editor.getController();
|
||||||
if (!controller || !controller.supportsCommand(cmd) || !controller.isCommandEnabled(cmd)) {
|
dactyl.assert(controller &&
|
||||||
dactyl.beep();
|
controller.supportsCommand(cmd) &&
|
||||||
return false;
|
controller.isCommandEnabled(cmd));
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof count != "number" || count < 1)
|
if (typeof count != "number" || count < 1)
|
||||||
count = 1;
|
count = 1;
|
||||||
@@ -116,13 +86,10 @@ const Editor = Module("editor", {
|
|||||||
didCommand = true;
|
didCommand = true;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
if (!didCommand)
|
dactyl.assert(didCommand);
|
||||||
dactyl.beep();
|
break;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// cmd = y, d, c
|
// cmd = y, d, c
|
||||||
@@ -316,10 +283,12 @@ const Editor = Module("editor", {
|
|||||||
let text = ""; // XXX
|
let text = ""; // XXX
|
||||||
if (textBox)
|
if (textBox)
|
||||||
text = textBox.value;
|
text = textBox.value;
|
||||||
else if (typeof GetCurrentEditor == "function") // Thunderbird composer
|
else {
|
||||||
text = GetCurrentEditor().outputToString("text/plain", 2);
|
var editor = window.GetCurrentEditor ? GetCurrentEditor()
|
||||||
else
|
: Editor.getEditor(document.commandDispatcher.focusedWindow);
|
||||||
return;
|
dactyl.assert(editor);
|
||||||
|
text = Array.map(editor.rootElement.childNodes, function (e) util.domToString(e, true)).join("");
|
||||||
|
}
|
||||||
|
|
||||||
let oldBg, tmpBg;
|
let oldBg, tmpBg;
|
||||||
try {
|
try {
|
||||||
@@ -330,8 +299,6 @@ const Editor = Module("editor", {
|
|||||||
tmpBg = "yellow";
|
tmpBg = "yellow";
|
||||||
textBox.style.backgroundColor = "#bbbbbb";
|
textBox.style.backgroundColor = "#bbbbbb";
|
||||||
}
|
}
|
||||||
else
|
|
||||||
var editor = GetCurrentEditor();
|
|
||||||
|
|
||||||
if (!tmpfile.write(text))
|
if (!tmpfile.write(text))
|
||||||
throw Error("Input contains characters not valid in the current " +
|
throw Error("Input contains characters not valid in the current " +
|
||||||
@@ -347,9 +314,9 @@ const Editor = Module("editor", {
|
|||||||
if (textBox)
|
if (textBox)
|
||||||
textBox.value = val;
|
textBox.value = val;
|
||||||
else {
|
else {
|
||||||
editor.selection.addRange(RangeFind.nodeRange(editor.rootNode));
|
while (editor.rootElement.firstChild)
|
||||||
editor.selection.deleteFromDocument();
|
editor.rootElement.removeChild(editor.rootElement.firstChild);
|
||||||
editor.insertText(val);
|
editor.rootElement.innerHTML = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,10 +384,25 @@ const Editor = Module("editor", {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
getEditor: function () dactyl.focus,
|
getEditor: function (elem) {
|
||||||
|
if (arguments.length === 0) {
|
||||||
|
dactyl.assert(dactyl.focus);
|
||||||
|
return dactyl.focus;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!elem)
|
||||||
|
elem = dactyl.focus || document.commandDispatcher.focusedWindow;
|
||||||
|
dactyl.assert(elem);
|
||||||
|
|
||||||
|
if (elem instanceof Element)
|
||||||
|
return elem.QueryInterface(Ci.nsIDOMNSEditableElement).editor;
|
||||||
|
return elem.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation)
|
||||||
|
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIEditingSession)
|
||||||
|
.getEditorForWindow(elem);
|
||||||
|
},
|
||||||
|
|
||||||
getController: function () {
|
getController: function () {
|
||||||
let ed = Editor.getEditor();
|
let ed = dactyl.focus;
|
||||||
if (!ed || !ed.controllers)
|
if (!ed || !ed.controllers)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
|||||||
@@ -659,8 +659,11 @@ const Events = Module("events", {
|
|||||||
let elem = event.originalTarget;
|
let elem = event.originalTarget;
|
||||||
|
|
||||||
if (Events.isContentNode(elem) && !buffer.focusAllowed(elem)
|
if (Events.isContentNode(elem) && !buffer.focusAllowed(elem)
|
||||||
&& isinstance(elem, [HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement]))
|
&& isinstance(elem, [HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement, Window]))
|
||||||
elem.blur();
|
if (elem.frameElement)
|
||||||
|
dactyl.focusContent(true);
|
||||||
|
else
|
||||||
|
elem.blur();
|
||||||
},
|
},
|
||||||
|
|
||||||
// argument "event" is deliberately not used, as i don't seem to have
|
// argument "event" is deliberately not used, as i don't seem to have
|
||||||
@@ -696,9 +699,12 @@ const Events = Module("events", {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elem instanceof HTMLTextAreaElement || (elem && util.computedStyle(elem).MozUserModify == "read-write")) {
|
if (elem instanceof HTMLTextAreaElement || (elem && util.computedStyle(elem).MozUserModify == "read-write")
|
||||||
|
|| elem == null && win && Editor.getEditor(win)) {
|
||||||
|
|
||||||
if (modes.main === modes.VISUAL && elem.selectionEnd == elem.selectionStart)
|
if (modes.main === modes.VISUAL && elem.selectionEnd == elem.selectionStart)
|
||||||
modes.pop();
|
modes.pop();
|
||||||
|
|
||||||
if (options["insertmode"])
|
if (options["insertmode"])
|
||||||
modes.set(modes.INSERT);
|
modes.set(modes.INSERT);
|
||||||
else {
|
else {
|
||||||
@@ -706,6 +712,7 @@ const Events = Module("events", {
|
|||||||
if (elem.selectionEnd - elem.selectionStart > 0)
|
if (elem.selectionEnd - elem.selectionStart > 0)
|
||||||
modes.push(modes.VISUAL);
|
modes.push(modes.VISUAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasHTMLDocument(win))
|
if (hasHTMLDocument(win))
|
||||||
buffer.lastInputField = elem;
|
buffer.lastInputField = elem;
|
||||||
return;
|
return;
|
||||||
@@ -720,8 +727,8 @@ const Events = Module("events", {
|
|||||||
if (elem == null && urlbar && urlbar.inputField == this._lastFocus)
|
if (elem == null && urlbar && urlbar.inputField == this._lastFocus)
|
||||||
util.threadYield(true);
|
util.threadYield(true);
|
||||||
|
|
||||||
if (modes.getMode(modes.main).ownsFocus)
|
while (modes.getMode(modes.main).ownsFocus)
|
||||||
modes.reset();
|
modes.pop();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
this._lastFocus = elem;
|
this._lastFocus = elem;
|
||||||
@@ -782,9 +789,6 @@ const Events = Module("events", {
|
|||||||
let stop = false;
|
let stop = false;
|
||||||
let mode = modes.getStack(0);
|
let mode = modes.getStack(0);
|
||||||
|
|
||||||
let win = document.commandDispatcher.focusedWindow;
|
|
||||||
if (win && win.document && "designMode" in win.document && win.document.designMode == "on" && !config.isComposeWindow)
|
|
||||||
stop = true;
|
|
||||||
// menus have their own command handlers
|
// menus have their own command handlers
|
||||||
if (modes.extended & modes.MENU)
|
if (modes.extended & modes.MENU)
|
||||||
stop = true;
|
stop = true;
|
||||||
@@ -985,7 +989,7 @@ const Events = Module("events", {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
isContentNode: function isContentNode(node) {
|
isContentNode: function isContentNode(node) {
|
||||||
let win = (node.ownerDocument || node).defaultView;
|
let win = (node.ownerDocument || node).defaultView || node;
|
||||||
for (; win; win = win.parent != win && win.parent)
|
for (; win; win = win.parent != win && win.parent)
|
||||||
if (win == window.content)
|
if (win == window.content)
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -485,8 +485,11 @@ function isObject(obj) typeof obj === "object" && obj != null;
|
|||||||
* any window, frame, namespace, or execution context, which
|
* any window, frame, namespace, or execution context, which
|
||||||
* is not the case when using (obj instanceof Array).
|
* is not the case when using (obj instanceof Array).
|
||||||
*/
|
*/
|
||||||
const isArray = Array.isArray ||
|
const isArray =
|
||||||
function isArray(val) objproto.toString.call(val) == "[object Array]";
|
Array.isArray
|
||||||
|
// This is bloody stupid.
|
||||||
|
? function isArray(val) Array.isArray(val) || val && val.constructor && val.constructor.name === "Array"
|
||||||
|
: function isArray(val) objproto.toString.call(val) == "[object Array]";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if and only if its sole argument is an
|
* Returns true if and only if its sole argument is an
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
|
|||||||
dequote: function dequote(pattern, chars)
|
dequote: function dequote(pattern, chars)
|
||||||
pattern.replace(/\\(.)/, function (m0, m1) chars.indexOf(m1) >= 0 ? m1 : m0),
|
pattern.replace(/\\(.)/, function (m0, m1) chars.indexOf(m1) >= 0 ? m1 : m0),
|
||||||
|
|
||||||
domToString: function (node) {
|
domToString: function (node, html) {
|
||||||
if (node instanceof Ci.nsISelection && node.isCollapsed)
|
if (node instanceof Ci.nsISelection && node.isCollapsed)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
@@ -282,6 +282,8 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
|
|||||||
|
|
||||||
let str = services.create("string");
|
let str = services.create("string");
|
||||||
str.data = encoder.encodeToString();
|
str.data = encoder.encodeToString();
|
||||||
|
if (html)
|
||||||
|
return str.data;
|
||||||
|
|
||||||
let [result, length] = [{}, {}];
|
let [result, length] = [{}, {}];
|
||||||
services.create("htmlConverter").convert("text/html", str, str.data.length*2, "text/unicode", result, length);
|
services.create("htmlConverter").convert("text/html", str, str.data.length*2, "text/unicode", result, length);
|
||||||
|
|||||||
Reference in New Issue
Block a user