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