mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-19 08:37:59 +01:00
Fix some of the more horrendous editor.js code.
--HG-- extra : rebase_source : 1675c92e880249d90a59576291254724fb863c4e
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
|
Copyright © 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
|
||||||
2007-2009 by Doug Kearns <dougkearns@gmail.com>
|
Copyright © 2007-2011 by Doug Kearns <dougkearns@gmail.com>
|
||||||
2008-2010 by Kris Maglione <maglione.k at Gmail>
|
Copyright © 2008-2011 by Kris Maglione <maglione.k at Gmail>
|
||||||
|
|
||||||
For a full list of authors, refer the AUTHORS file.
|
For a full list of authors, refer the AUTHORS file.
|
||||||
|
|
||||||
|
|||||||
@@ -12,22 +12,44 @@
|
|||||||
|
|
||||||
/** @instance editor */
|
/** @instance editor */
|
||||||
var Editor = Module("editor", {
|
var Editor = Module("editor", {
|
||||||
|
init: function init(elem) {
|
||||||
|
if (elem)
|
||||||
|
this.element = elem;
|
||||||
|
else
|
||||||
|
this.__defineGetter__("element", function () {
|
||||||
|
let elem = dactyl.focusedElement;
|
||||||
|
if (elem)
|
||||||
|
return elem.inputField || elem;
|
||||||
|
|
||||||
|
let win = document.commandDispatcher.focusedWindow;
|
||||||
|
return DOM(win).isEditable && win;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
get editor() DOM(this.element).editor,
|
||||||
|
|
||||||
|
getController: function getController(cmd) {
|
||||||
|
let controllers = this.element && this.element.controllers;
|
||||||
|
dactyl.assert(controllers);
|
||||||
|
|
||||||
|
return controllers.getControllerForCommand(cmd || "cmd_beginLine");
|
||||||
|
},
|
||||||
|
|
||||||
|
get selection() this.editor && this.editor.selection,
|
||||||
|
|
||||||
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,
|
||||||
|
|
||||||
unselectText: function (toEnd) {
|
deselectText: function () {
|
||||||
try {
|
if (this.selection)
|
||||||
Editor.getEditor(null).selection[toEnd ? "collapseToEnd" : "collapseToStart"]();
|
this.selection.collapse(this.selection.focusNode,
|
||||||
}
|
this.selection.focusOffset);
|
||||||
catch (e) {}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
selectedText: function () String(Editor.getEditor(null).selection),
|
get selectedText() String(this.selection),
|
||||||
|
|
||||||
pasteClipboard: function (clipboard, toStart) {
|
pasteClipboard: function (clipboard, toStart) {
|
||||||
let elem = dactyl.focusedElement;
|
let elem = this.element;
|
||||||
if (elem.inputField)
|
|
||||||
elem = elem.inputField;
|
|
||||||
|
|
||||||
if (elem.setSelectionRange) {
|
if (elem.setSelectionRange) {
|
||||||
let text = dactyl.clipboardRead(clipboard);
|
let text = dactyl.clipboardRead(clipboard);
|
||||||
@@ -47,7 +69,7 @@ var Editor = Module("editor", {
|
|||||||
elem.value = value;
|
elem.value = value;
|
||||||
|
|
||||||
if (/^(search|text)$/.test(elem.type))
|
if (/^(search|text)$/.test(elem.type))
|
||||||
Editor.getEditor(elem).rootElement.firstChild.textContent = value;
|
DOM(elem).rootElement.firstChild.textContent = value;
|
||||||
|
|
||||||
elem.selectionStart = Math.min(start + (toStart ? 0 : text.length), elem.value.length);
|
elem.selectionStart = Math.min(start + (toStart ? 0 : text.length), elem.value.length);
|
||||||
elem.selectionEnd = elem.selectionStart;
|
elem.selectionEnd = elem.selectionStart;
|
||||||
@@ -61,8 +83,7 @@ var Editor = Module("editor", {
|
|||||||
|
|
||||||
// count is optional, defaults to 1
|
// count is optional, defaults to 1
|
||||||
executeCommand: function (cmd, count) {
|
executeCommand: function (cmd, count) {
|
||||||
let editor = Editor.getEditor(null);
|
let controller = this.getController(cmd);
|
||||||
let controller = Editor.getController(cmd);
|
|
||||||
dactyl.assert(callable(cmd) ||
|
dactyl.assert(callable(cmd) ||
|
||||||
controller &&
|
controller &&
|
||||||
controller.supportsCommand(cmd) &&
|
controller.supportsCommand(cmd) &&
|
||||||
@@ -79,7 +100,7 @@ var Editor = Module("editor", {
|
|||||||
// good thing is, we need this code anyway for proper beeping
|
// good thing is, we need this code anyway for proper beeping
|
||||||
try {
|
try {
|
||||||
if (callable(cmd))
|
if (callable(cmd))
|
||||||
cmd(editor, controller);
|
cmd(this.editor, controller);
|
||||||
else
|
else
|
||||||
controller.doCommand(cmd);
|
controller.doCommand(cmd);
|
||||||
didCommand = true;
|
didCommand = true;
|
||||||
@@ -92,41 +113,14 @@ var Editor = Module("editor", {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// This function will move/select up to given "pos"
|
moveToPosition: function (pos, select) {
|
||||||
// Simple setSelectionRange() would be better, but we want to maintain the correct
|
let node = this.selection.focusNode;
|
||||||
// order of selectionStart/End (a Gecko bug always makes selectionStart <= selectionEnd)
|
this.selection[select ? "extend" : "collapse"](node, pos);
|
||||||
// Use only for small movements!
|
|
||||||
moveToPosition: function (pos, forward, select) {
|
|
||||||
if (!select) {
|
|
||||||
Editor.getEditor().setSelectionRange(pos, pos);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (forward) {
|
|
||||||
if (pos <= Editor.getEditor().selectionEnd || pos > Editor.getEditor().value.length)
|
|
||||||
return;
|
|
||||||
|
|
||||||
do { // TODO: test code for endless loops
|
|
||||||
this.executeCommand("cmd_selectCharNext", 1);
|
|
||||||
}
|
|
||||||
while (Editor.getEditor().selectionEnd != pos);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (pos >= Editor.getEditor().selectionStart || pos < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
do { // TODO: test code for endless loops
|
|
||||||
this.executeCommand("cmd_selectCharPrevious", 1);
|
|
||||||
}
|
|
||||||
while (Editor.getEditor().selectionStart != pos);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
findChar: function (key, count, backward) {
|
findChar: function (key, count, backward) {
|
||||||
|
|
||||||
let editor = Editor.getEditor();
|
util.assert(DOM(this.element).isInput);
|
||||||
if (!editor)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// XXX
|
// XXX
|
||||||
if (count == null)
|
if (count == null)
|
||||||
@@ -134,10 +128,11 @@ var Editor = Module("editor", {
|
|||||||
|
|
||||||
let code = DOM.Event.parse(key)[0].charCode;
|
let code = DOM.Event.parse(key)[0].charCode;
|
||||||
util.assert(code);
|
util.assert(code);
|
||||||
|
|
||||||
let char = String.fromCharCode(code);
|
let char = String.fromCharCode(code);
|
||||||
|
|
||||||
let text = editor.value;
|
let text = this.element.value;
|
||||||
let caret = editor.selectionEnd;
|
let caret = this.element.selectionEnd;
|
||||||
if (backward) {
|
if (backward) {
|
||||||
let end = text.lastIndexOf("\n", caret);
|
let end = text.lastIndexOf("\n", caret);
|
||||||
while (caret > end && caret >= 0 && count--)
|
while (caret > end && caret >= 0 && count--)
|
||||||
@@ -309,8 +304,8 @@ var Editor = Module("editor", {
|
|||||||
* @see Abbreviation#expand
|
* @see Abbreviation#expand
|
||||||
*/
|
*/
|
||||||
expandAbbreviation: function (mode) {
|
expandAbbreviation: function (mode) {
|
||||||
let elem = dactyl.focusedElement;
|
let elem = this.element;
|
||||||
if (!(elem && elem.value))
|
if (!DOM(elem).isInput && elem.value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let text = elem.value;
|
let text = elem.value;
|
||||||
@@ -408,14 +403,20 @@ var Editor = Module("editor", {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let node = range[forward ? "endContainer" : "startContainer"];
|
||||||
|
let iterator = Editor.TextsIterator(root || node.ownerDocument.documentElement,
|
||||||
|
node);
|
||||||
|
|
||||||
|
if (!(node instanceof Ci.nsIDOMText)) {
|
||||||
|
node = iterator[forward ? "getNext" : "getPrev"]();
|
||||||
|
range[forward ? "setEnd" : "setStart"](node, forward ? 0 : node.textContent.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
let text = range[forward ? "endContainer" : "startContainer"].textContent;
|
let text = range[forward ? "endContainer" : "startContainer"].textContent;
|
||||||
let idx = range[forward ? "endOffset" : "startOffset"];
|
let idx = range[forward ? "endOffset" : "startOffset"];
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
|
|
||||||
let node = range.startContainer;
|
|
||||||
let iterator = Editor.TextsIterator(root || node.ownerDocument.documentElement,
|
|
||||||
node);
|
|
||||||
|
|
||||||
if (forward) {
|
if (forward) {
|
||||||
advance(true);
|
advance(true);
|
||||||
if (!sameWord)
|
if (!sameWord)
|
||||||
@@ -440,29 +441,18 @@ var Editor = Module("editor", {
|
|||||||
dactyl.assert(elem);
|
dactyl.assert(elem);
|
||||||
|
|
||||||
return DOM(elem).editor;
|
return DOM(elem).editor;
|
||||||
},
|
|
||||||
|
|
||||||
getController: function (cmd) {
|
|
||||||
let win = document.commandDispatcher.focusedWindow;
|
|
||||||
let ed = dactyl.focusedElement || Editor.getEditor(win) && win;
|
|
||||||
if (!ed || !ed.controllers)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return ed.controllers.getControllerForCommand(cmd || "cmd_beginLine");
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
mappings: function () {
|
mappings: function () {
|
||||||
|
|
||||||
Map.types["editor"] = {
|
Map.types["editor"] = {
|
||||||
preExecute: function preExecute(args) {
|
preExecute: function preExecute(args) {
|
||||||
let editor = Editor.getEditor(null)
|
if (editor.editor)
|
||||||
if (editor)
|
editor.editor.beginTransaction();
|
||||||
editor.beginTransaction();
|
|
||||||
},
|
},
|
||||||
postExecute: function preExecute(args) {
|
postExecute: function preExecute(args) {
|
||||||
let editor = Editor.getEditor(null)
|
if (editor.editor)
|
||||||
if (editor)
|
editor.editor.endTransaction();
|
||||||
editor.endTransaction();
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
Map.types["operator"] = {
|
Map.types["operator"] = {
|
||||||
@@ -501,14 +491,14 @@ var Editor = Module("editor", {
|
|||||||
count = count || 1;
|
count = count || 1;
|
||||||
|
|
||||||
let caret = !dactyl.focusedElement;
|
let caret = !dactyl.focusedElement;
|
||||||
let editor_ = Editor.getEditor(null);
|
|
||||||
let controller = buffer.selectionController;
|
let controller = buffer.selectionController;
|
||||||
|
|
||||||
while (count-- && modes.main == modes.VISUAL) {
|
while (count-- && modes.main == modes.VISUAL) {
|
||||||
if (caret)
|
if (caret)
|
||||||
caretExecute(true, true);
|
caretExecute(true, true);
|
||||||
else {
|
else {
|
||||||
if (callable(visualTextEditCommand))
|
if (callable(visualTextEditCommand))
|
||||||
visualTextEditCommand(editor_);
|
visualTextEditCommand(editor.editor);
|
||||||
else
|
else
|
||||||
editor.executeCommand(visualTextEditCommand);
|
editor.executeCommand(visualTextEditCommand);
|
||||||
}
|
}
|
||||||
@@ -520,7 +510,7 @@ var Editor = Module("editor", {
|
|||||||
function ({ count }) {
|
function ({ count }) {
|
||||||
count = count || 1;
|
count = count || 1;
|
||||||
|
|
||||||
if (Editor.getEditor(null))
|
if (editor.editor)
|
||||||
editor.executeCommand(textEditCommand, count);
|
editor.executeCommand(textEditCommand, count);
|
||||||
else {
|
else {
|
||||||
while (count--)
|
while (count--)
|
||||||
@@ -534,8 +524,7 @@ var Editor = Module("editor", {
|
|||||||
function addBeginInsertModeMap(keys, commands, description) {
|
function addBeginInsertModeMap(keys, commands, description) {
|
||||||
mappings.add([modes.TEXT_EDIT], keys, description || "",
|
mappings.add([modes.TEXT_EDIT], keys, description || "",
|
||||||
function () {
|
function () {
|
||||||
commands.forEach(function (cmd)
|
commands.forEach(function (cmd) { editor.executeCommand(cmd, 1) });
|
||||||
editor.executeCommand(cmd, 1));
|
|
||||||
modes.push(modes.INSERT);
|
modes.push(modes.INSERT);
|
||||||
},
|
},
|
||||||
{ type: "editor" });
|
{ type: "editor" });
|
||||||
@@ -543,13 +532,13 @@ var Editor = Module("editor", {
|
|||||||
|
|
||||||
function selectPreviousLine() {
|
function selectPreviousLine() {
|
||||||
editor.executeCommand("cmd_selectLinePrevious");
|
editor.executeCommand("cmd_selectLinePrevious");
|
||||||
if ((modes.extended & modes.LINE) && !editor.selectedText())
|
if ((modes.extended & modes.LINE) && !editor.selectedText)
|
||||||
editor.executeCommand("cmd_selectLinePrevious");
|
editor.executeCommand("cmd_selectLinePrevious");
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectNextLine() {
|
function selectNextLine() {
|
||||||
editor.executeCommand("cmd_selectLineNext");
|
editor.executeCommand("cmd_selectLineNext");
|
||||||
if ((modes.extended & modes.LINE) && !editor.selectedText())
|
if ((modes.extended & modes.LINE) && !editor.selectedText)
|
||||||
editor.executeCommand("cmd_selectLineNext");
|
editor.executeCommand("cmd_selectLineNext");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -562,19 +551,23 @@ var Editor = Module("editor", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function clear(forward, re)
|
function clear(forward, re)
|
||||||
function _clear(editor, elem) {
|
function _clear(editor) {
|
||||||
updateRange(editor, forward, re, function (range) {});
|
updateRange(editor, forward, re, function (range) {});
|
||||||
editor.selection.deleteFromDocument();
|
editor.selection.deleteFromDocument();
|
||||||
DOM(elem).input();
|
let parent = DOM(editor.rootElement.parentNode);
|
||||||
|
if (parent.isInput)
|
||||||
|
parent.input();
|
||||||
}
|
}
|
||||||
|
|
||||||
function move(forward, re)
|
function move(forward, re)
|
||||||
function _move(editor) {
|
function _move(editor) {
|
||||||
updateRange(editor, forward, re, function (range) { range.collapse(!forward); });
|
updateRange(editor, forward, re,
|
||||||
|
function (range) { range.collapse(!forward); });
|
||||||
}
|
}
|
||||||
function select(forward, re)
|
function select(forward, re)
|
||||||
function _select(editor) {
|
function _select(editor) {
|
||||||
updateRange(editor, forward, re, function (range) {});
|
updateRange(editor, forward, re,
|
||||||
|
function (range) {});
|
||||||
}
|
}
|
||||||
function beginLine(editor_) {
|
function beginLine(editor_) {
|
||||||
editor.executeCommand("cmd_beginLine");
|
editor.executeCommand("cmd_beginLine");
|
||||||
@@ -591,7 +584,7 @@ var Editor = Module("editor", {
|
|||||||
addMovementMap(["l", "<Right>", "<Space>"], "Move right one character",
|
addMovementMap(["l", "<Right>", "<Space>"], "Move right one character",
|
||||||
true, "characterMove", true, "cmd_charNext", "cmd_selectCharNext");
|
true, "characterMove", true, "cmd_charNext", "cmd_selectCharNext");
|
||||||
addMovementMap(["b", "<C-Left>"], "Move left one word",
|
addMovementMap(["b", "<C-Left>"], "Move left one word",
|
||||||
true, "wordMove", false, "cmd_wordPrevious", "cmd_selectWordPrevious");
|
true, "wordMove", false, move(false, /\w/), select(false, /\w/));
|
||||||
addMovementMap(["w", "<C-Right>"], "Move right one word",
|
addMovementMap(["w", "<C-Right>"], "Move right one word",
|
||||||
true, "wordMove", true, move(true, /\w/), select(true, /\w/));
|
true, "wordMove", true, move(true, /\w/), select(true, /\w/));
|
||||||
addMovementMap(["B"], "Move left to the previous white space",
|
addMovementMap(["B"], "Move left to the previous white space",
|
||||||
@@ -637,15 +630,15 @@ var Editor = Module("editor", {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
editor.beginTransaction();
|
editor_.beginTransaction();
|
||||||
|
|
||||||
let range = RangeFind.union(start, sel.getRangeAt(0));
|
let range = RangeFind.union(start, sel.getRangeAt(0));
|
||||||
sel.removeAllRanges();
|
sel.removeAllRanges();
|
||||||
sel.addRange(select ? range : start);
|
sel.addRange(select ? range : start);
|
||||||
cmd(editor, range);
|
cmd(editor_, range);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
editor.endTransaction();
|
editor_.endTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
modes.delay(function () {
|
modes.delay(function () {
|
||||||
@@ -655,7 +648,7 @@ var Editor = Module("editor", {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let editor = Editor.getEditor(null);
|
let editor_ = editor.editor;
|
||||||
let sel = editor.selection;
|
let sel = editor.selection;
|
||||||
let start = sel.getRangeAt(0).cloneRange();
|
let start = sel.getRangeAt(0).cloneRange();
|
||||||
},
|
},
|
||||||
@@ -672,8 +665,8 @@ var Editor = Module("editor", {
|
|||||||
|
|
||||||
bind(["<C-w>"], "Delete previous word",
|
bind(["<C-w>"], "Delete previous word",
|
||||||
function () {
|
function () {
|
||||||
if (DOM(dactyl.focusedElement).isInput)
|
if (editor.editor)
|
||||||
clear(false, /\w/)(Editor.getEditor(null), dactyl.focusedElement);
|
clear(false, /\w/)(editor.editor);
|
||||||
else
|
else
|
||||||
editor.executeCommand("cmd_deleteWordBackward", 1);
|
editor.executeCommand("cmd_deleteWordBackward", 1);
|
||||||
});
|
});
|
||||||
@@ -682,14 +675,14 @@ var Editor = Module("editor", {
|
|||||||
function () {
|
function () {
|
||||||
// Deletes the whole line. What the hell.
|
// Deletes the whole line. What the hell.
|
||||||
// editor.executeCommand("cmd_deleteToBeginningOfLine", 1);
|
// editor.executeCommand("cmd_deleteToBeginningOfLine", 1);
|
||||||
let editor_ = Editor.getEditor(null);
|
|
||||||
|
|
||||||
editor.executeCommand("cmd_selectBeginLine", 1);
|
editor.executeCommand("cmd_selectBeginLine", 1);
|
||||||
if (editor_ && editor_.selection.isCollapsed) {
|
if (editor.selection && editor.selection.isCollapsed) {
|
||||||
editor.executeCommand("cmd_deleteCharBackward", 1);
|
editor.executeCommand("cmd_deleteCharBackward", 1);
|
||||||
editor.executeCommand("cmd_selectBeginLine", 1);
|
editor.executeCommand("cmd_selectBeginLine", 1);
|
||||||
}
|
}
|
||||||
if (Editor.getController().isCommandEnabled("cmd_delete"))
|
|
||||||
|
if (editor.getController("cmd_delete").isCommandEnabled("cmd_delete"))
|
||||||
editor.executeCommand("cmd_delete", 1);
|
editor.executeCommand("cmd_delete", 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -717,8 +710,13 @@ var Editor = Module("editor", {
|
|||||||
|
|
||||||
bind(["<C-t>"], "Edit text field in Text Edit mode",
|
bind(["<C-t>"], "Edit text field in Text Edit mode",
|
||||||
function () {
|
function () {
|
||||||
dactyl.assert(!editor.isTextEdit && Editor.getEditor(null));
|
dactyl.assert(!editor.isTextEdit && editor.editor);
|
||||||
dactyl.assert(dactyl.focusedElement ||
|
dactyl.assert(dactyl.focusedElement ||
|
||||||
|
// Sites like Google like to use a
|
||||||
|
// hidden, editable window for keyboard
|
||||||
|
// focus and use their own WYSIWYG editor
|
||||||
|
// implementations for the visible area,
|
||||||
|
// which we can't handle.
|
||||||
let (f = document.commandDispatcher.focusedWindow.frameElement)
|
let (f = document.commandDispatcher.focusedWindow.frameElement)
|
||||||
f && Hints.isVisible(f, true));
|
f && Hints.isVisible(f, true));
|
||||||
|
|
||||||
@@ -753,7 +751,7 @@ var Editor = Module("editor", {
|
|||||||
["u"], "Undo changes",
|
["u"], "Undo changes",
|
||||||
function (args) {
|
function (args) {
|
||||||
editor.executeCommand("cmd_undo", Math.max(args.count, 1));
|
editor.executeCommand("cmd_undo", Math.max(args.count, 1));
|
||||||
editor.unselectText();
|
editor.deselectText();
|
||||||
},
|
},
|
||||||
{ count: true });
|
{ count: true });
|
||||||
|
|
||||||
@@ -761,7 +759,7 @@ var Editor = Module("editor", {
|
|||||||
["<C-r>"], "Redo undone changes",
|
["<C-r>"], "Redo undone changes",
|
||||||
function (args) {
|
function (args) {
|
||||||
editor.executeCommand("cmd_redo", Math.max(args.count, 1));
|
editor.executeCommand("cmd_redo", Math.max(args.count, 1));
|
||||||
editor.unselectText();
|
editor.deselectText();
|
||||||
},
|
},
|
||||||
{ count: true });
|
{ count: true });
|
||||||
|
|
||||||
@@ -845,7 +843,8 @@ var Editor = Module("editor", {
|
|||||||
{ count: true });
|
{ count: true });
|
||||||
|
|
||||||
let bind = function bind(names, description, action, params)
|
let bind = function bind(names, description, action, params)
|
||||||
mappings.add([modes.TEXT_EDIT, modes.OPERATOR], names, description,
|
mappings.add([modes.TEXT_EDIT, modes.OPERATOR, modes.VISUAL],
|
||||||
|
names, description,
|
||||||
action, update({ type: "editor" }, params));
|
action, update({ type: "editor" }, params));
|
||||||
|
|
||||||
// finding characters
|
// finding characters
|
||||||
@@ -861,7 +860,8 @@ var Editor = Module("editor", {
|
|||||||
function ({ arg, count }) {
|
function ({ arg, count }) {
|
||||||
let pos = editor.findChar(arg, Math.max(count, 1));
|
let pos = editor.findChar(arg, Math.max(count, 1));
|
||||||
if (pos >= 0)
|
if (pos >= 0)
|
||||||
editor.moveToPosition(offset(false, false, pos), true, modes.main == modes.VISUAL);
|
editor.moveToPosition(offset(false, false, pos),
|
||||||
|
modes.main == modes.VISUAL);
|
||||||
},
|
},
|
||||||
{ arg: true, count: true, type: "operator" });
|
{ arg: true, count: true, type: "operator" });
|
||||||
|
|
||||||
@@ -869,7 +869,8 @@ var Editor = Module("editor", {
|
|||||||
function ({ arg, count }) {
|
function ({ arg, count }) {
|
||||||
let pos = editor.findChar(arg, Math.max(count, 1), true);
|
let pos = editor.findChar(arg, Math.max(count, 1), true);
|
||||||
if (pos >= 0)
|
if (pos >= 0)
|
||||||
editor.moveToPosition(offset(true, false, pos), false, modes.main == modes.VISUAL);
|
editor.moveToPosition(offset(true, false, pos),
|
||||||
|
modes.main == modes.VISUAL);
|
||||||
},
|
},
|
||||||
{ arg: true, count: true, type: "operator" });
|
{ arg: true, count: true, type: "operator" });
|
||||||
|
|
||||||
@@ -877,7 +878,8 @@ var Editor = Module("editor", {
|
|||||||
function ({ arg, count }) {
|
function ({ arg, count }) {
|
||||||
let pos = editor.findChar(arg, Math.max(count, 1));
|
let pos = editor.findChar(arg, Math.max(count, 1));
|
||||||
if (pos >= 0)
|
if (pos >= 0)
|
||||||
editor.moveToPosition(offset(false, true, pos), true, modes.main == modes.VISUAL);
|
editor.moveToPosition(offset(false, true, pos),
|
||||||
|
modes.main == modes.VISUAL);
|
||||||
},
|
},
|
||||||
{ arg: true, count: true, type: "operator" });
|
{ arg: true, count: true, type: "operator" });
|
||||||
|
|
||||||
@@ -885,30 +887,50 @@ var Editor = Module("editor", {
|
|||||||
function ({ arg, count }) {
|
function ({ arg, count }) {
|
||||||
let pos = editor.findChar(arg, Math.max(count, 1), true);
|
let pos = editor.findChar(arg, Math.max(count, 1), true);
|
||||||
if (pos >= 0)
|
if (pos >= 0)
|
||||||
editor.moveToPosition(offset(true, true, pos), false, modes.main == modes.VISUAL);
|
editor.moveToPosition(offset(true, true, pos),
|
||||||
|
modes.main == modes.VISUAL);
|
||||||
},
|
},
|
||||||
{ arg: true, count: true, type: "operator" });
|
{ arg: true, count: true, type: "operator" });
|
||||||
|
|
||||||
|
function mungeRange(range, munger) {
|
||||||
|
let text = munger(range);
|
||||||
|
let { startOffset, endOffset } = range;
|
||||||
|
let root = range.startContainer.parentNode;
|
||||||
|
|
||||||
|
range.deleteContents();
|
||||||
|
range.insertNode(range.startContainer.ownerDocument
|
||||||
|
.createTextNode(text));
|
||||||
|
root.normalize();
|
||||||
|
range.setStart(root.firstChild, startOffset);
|
||||||
|
range.setEnd(root.firstChild, endOffset);
|
||||||
|
}
|
||||||
|
|
||||||
// text edit and visual mode
|
// text edit and visual mode
|
||||||
mappings.add([modes.TEXT_EDIT, modes.VISUAL],
|
mappings.add([modes.TEXT_EDIT, modes.VISUAL],
|
||||||
["~"], "Switch case of the character under the cursor and move the cursor to the right",
|
["~"], "Switch case of the character under the cursor and move the cursor to the right",
|
||||||
function ({ count }) {
|
function ({ count }) {
|
||||||
if (modes.main == modes.VISUAL)
|
function munger(range)
|
||||||
count = Editor.getEditor().selectionEnd - Editor.getEditor().selectionStart;
|
String(range).replace(/./g, function (c) {
|
||||||
count = Math.max(count, 1);
|
let lc = c.toLocaleLowerCase();
|
||||||
|
return c == lc ? c.toLocaleUpperCase() : lc;
|
||||||
|
});
|
||||||
|
|
||||||
// FIXME: do this in one pass?
|
var range = editor.selection.getRangeAt(0);
|
||||||
while (count-- > 0) {
|
// Ugh. TODO: Utility.
|
||||||
let text = Editor.getEditor().value;
|
if (!(range.startContainer instanceof Ci.nsIDOMText)) {
|
||||||
let pos = Editor.getEditor().selectionStart;
|
range = RangeFind.nodeContants(node.startContainer);
|
||||||
dactyl.assert(pos < text.length);
|
range.collapse(false);
|
||||||
|
|
||||||
let chr = text[pos];
|
|
||||||
Editor.getEditor().value = text.substring(0, pos) +
|
|
||||||
(chr == chr.toLocaleLowerCase() ? chr.toLocaleUpperCase() : chr.toLocaleLowerCase()) +
|
|
||||||
text.substring(pos + 1);
|
|
||||||
editor.moveToPosition(pos + 1, true, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (range.collapsed) {
|
||||||
|
count = count || 1;
|
||||||
|
|
||||||
|
range.setEnd(range.startContainer,
|
||||||
|
range.startOffset + count);
|
||||||
|
}
|
||||||
|
mungeRange(range, munger);
|
||||||
|
editor.selection.collapse(range.startContainer, range.endOffset);
|
||||||
|
|
||||||
modes.pop(modes.TEXT_EDIT);
|
modes.pop(modes.TEXT_EDIT);
|
||||||
},
|
},
|
||||||
{ count: true });
|
{ count: true });
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ var Modes = Module("modes", {
|
|||||||
selection.collapseToStart();
|
selection.collapseToStart();
|
||||||
}
|
}
|
||||||
else if (stack.pop)
|
else if (stack.pop)
|
||||||
editor.unselectText();
|
editor.deselectText();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.addMode("CARET", {
|
this.addMode("CARET", {
|
||||||
@@ -670,7 +670,7 @@ var Modes = Module("modes", {
|
|||||||
|
|
||||||
options.add(["passunknown", "pu"],
|
options.add(["passunknown", "pu"],
|
||||||
"Pass through unknown keys in these modes",
|
"Pass through unknown keys in these modes",
|
||||||
"stringlist", "!text_edit,base",
|
"stringlist", "!text_edit,!visual,base",
|
||||||
opts);
|
opts);
|
||||||
|
|
||||||
options.add(["showmode", "smd"],
|
options.add(["showmode", "smd"],
|
||||||
|
|||||||
@@ -313,8 +313,7 @@ var Buffer = Module("Buffer", {
|
|||||||
|
|
||||||
// Hack to deal with current versions of Firefox misplacing
|
// Hack to deal with current versions of Firefox misplacing
|
||||||
// the caret
|
// the caret
|
||||||
if (!overlay.getData(elem, "had-focus", false) &&
|
if (!overlay.getData(elem, "had-focus", false) && elem.value &&
|
||||||
elem.value &&
|
|
||||||
elem instanceof Ci.nsIDOMHTMLInputElement &&
|
elem instanceof Ci.nsIDOMHTMLInputElement &&
|
||||||
DOM(elem).isEditable &&
|
DOM(elem).isEditable &&
|
||||||
elem.selectionStart != null &&
|
elem.selectionStart != null &&
|
||||||
|
|||||||
Reference in New Issue
Block a user