1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-20 10:17: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:
Kris Maglione
2010-10-24 20:21:14 -04:00
parent 6f95b33694
commit dc38a2208c
8 changed files with 86 additions and 76 deletions

View File

@@ -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;

View File

@@ -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,

View File

@@ -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;

View File

@@ -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();
}, },

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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);