diff --git a/common/content/buffer.js b/common/content/buffer.js index 862ec5c3..49a795ee 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -517,33 +517,27 @@ var Buffer = Module("buffer", { * null, it tries to guess the word that the caret is * positioned in. * - * NOTE: might change the selection - * * @returns {string} */ getCurrentWord: function (win) { - win = win || this.focusedFrame || content; let selection = win.getSelection(); if (selection.rangeCount == 0) return ""; - let range = selection.getRangeAt(0); - if (selection.isCollapsed) { - let controller = util.selectionController(win); - let caretmode = controller.getCaretEnabled(); - controller.setCaretEnabled(true); - - // Only move backwards if the previous character is not a space. - if (range.startOffset > 0 && !/\s/.test(range.startContainer.textContent[range.startOffset - 1])) - controller.wordMove(false, false); - - controller.wordMove(true, true); - controller.setCaretEnabled(caretmode); - return String.match(selection, /\w*/)[0]; + let range = selection.getRangeAt(0).cloneRange(); + if (range.collapsed) { + let re = options.get("iskeyword").regexp; + util.dump(String.quote(range)); + Editor.extendRange(range, true, re, true); + util.dump(String.quote(range)); + Editor.extendRange(range, false, re, true); + util.dump(String.quote(range) + "\n\n\n"); } return util.domToString(range); }, + get currentWord() this.getCurrentWord(this.focusedFrame), + /** * Returns true if a scripts are allowed to focus the given input * element or input elements in the given window. @@ -1836,7 +1830,7 @@ var Buffer = Module("buffer", { mappings.add(myModes, ["Y", ""], "Copy selected text or current word", function () { - let sel = buffer.getCurrentWord(); + let sel = buffer.currentWord; dactyl.assert(sel); dactyl.clipboardWrite(sel, true); }); @@ -1902,6 +1896,17 @@ var Buffer = Module("buffer", { function () { buffer.showPageInfo(true); }); }, options: function () { + options.add(["iskeyword", "isk"], + "Regular expression defining which characters constitute word characters", + "string", '[^\\s.,!?:;/"\'^$%&?()[\\]{}<>#*+|=~_-]', + { + setter: function (value) { + this.regexp = util.regexp(value); + return value; + }, + validator: function (value) RegExp(value) + }); + options.add(["nextpattern"], "Patterns to use when guessing the next page in a document sequence", "regexplist", UTF8("'\\bnext\\b',^>$,^(>>|»)$,^(>|»),(>|»)$,'\\bmore\\b'"), diff --git a/common/content/editor.js b/common/content/editor.js index 4bdc737d..c6a80bd3 100644 --- a/common/content/editor.js +++ b/common/content/editor.js @@ -387,6 +387,38 @@ var Editor = Module("editor", { } }, }, { + extendRange: function extendRange(range, forward, re, sameWord) { + // FIXME: This could be so much simpler if I had more sleep. + function advance(positive) { + let tmp = range.cloneRange(); + while (tmp.endOffset < nodeRange.endOffset) { + tmp.setEnd(tmp.endContainer, tmp.endOffset + 1); + if (!re.test(String.slice(tmp, -1)) == positive) + break; + range.setEnd(tmp.endContainer, tmp.endOffset); + } + } + function retreat(positive) { + let tmp = range.cloneRange(); + while (tmp.startOffset > 0) { + tmp.setStart(tmp.startContainer, tmp.startOffset - 1); + if (re.test(String(tmp)[0]) == positive) + break; + range.setStart(tmp.startContainer, tmp.startOffset); + } + } + + let nodeRange = range.cloneRange(); + nodeRange.selectNodeContents(range.startContainer); + + let charge = forward ? advance : retreat; + + charge(true); + if (!sameWord || !forward) + charge(false); + return range; + }, + getEditor: function (elem) { if (arguments.length === 0) { dactyl.assert(dactyl.focusedElement); @@ -520,35 +552,8 @@ var Editor = Module("editor", { } function updateRange(editor, forward, re, modify) { - // FIXME: This could be so much simpler if I had more sleep. - function advance(positive) { - let tmp = range.cloneRange(); - while (tmp.endOffset < nodeRange.endOffset) { - tmp.setEnd(tmp.endContainer, tmp.endOffset + 1); - if (!re.test(String.slice(tmp, -1)) == positive) - break; - range.setEnd(tmp.endContainer, tmp.endOffset); - } - } - function retreat(positive) { - let tmp = range.cloneRange(); - while (tmp.startOffset > 0) { - tmp.setStart(tmp.startContainer, tmp.startOffset - 1); - if (re.test(String(tmp)[0]) == positive) - break; - range.setStart(tmp.startContainer, tmp.startOffset); - } - } - - let range = editor.selection.getRangeAt(0).cloneRange(); - let nodeRange = range.cloneRange(); - nodeRange.selectNodeContents(range.startContainer); - - let charge = forward ? advance : retreat; - - charge(true); - charge(false); - + let range = Editor.extendRange(editor.selection.getRangeAt(0), + forward, re, false); modify(range); editor.selection.removeAllRanges(); editor.selection.addRange(range); @@ -749,7 +754,7 @@ var Editor = Module("editor", { modes.pop(); } else - dactyl.clipboardWrite(buffer.getCurrentWord(), true); + dactyl.clipboardWrite(buffer.currentWord, true); }); mappings.add([modes.VISUAL, modes.TEXT_EDIT],