Skip to content

Commit

Permalink
CodeMirror vim editor support (#1921)
Browse files Browse the repository at this point in the history
* Fix invalid version number format and add @pixi/extensions since it's a missing dependency.

* Add support for editing CodeMirror elements through the vim editor. Addresses issue #140.

* Fix issue that caused CodeMirror line numbers to be pulled into the vim editor

* Correct 'Cusor' to 'Cursor' for 'moveCursorEOL'.

* Fix cursor not moving to EOL for CodeMirror elements.

* Refine setEndOfContenteditable by removing IE control flow and its logic.

* Remove the red dot (char code 8226) that CodeMirror uses to visualize the zero-width space.
  • Loading branch information
colossatr0n authored Dec 20, 2022
1 parent 3999da7 commit d514896
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ coverage/
package-lock.json
jsconfig.json
src/content_scripts/safari.js
*~
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Surfingkeys",
"version": "1.12",
"version": "1.12.0",
"description": "Map your keys for web surfing, expand your browser with javascript and keyboard.",
"main": "background.js",
"directories": {
Expand Down Expand Up @@ -68,6 +68,7 @@
"@pixi/ticker": "^6.2.1",
"@pixi/unsafe-eval": "^6.2.1",
"@pixi/utils": "^6.2.1",
"@pixi/extensions": "^6.2.1",
"ace-builds": "^1.4.12",
"dompurify": "^2.3.1",
"js-base64": "^3.7.2",
Expand Down
23 changes: 19 additions & 4 deletions src/content_scripts/common/insert.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
function createInsert() {
var self = new Mode("Insert");

function moveCusorEOL() {
function moveCursorEOL() {
var element = getRealEdit();
if (element.setSelectionRange !== undefined) {
try {
Expand All @@ -32,7 +32,12 @@ function createInsert() {
if (node.nodeType === Node.TEXT_NODE) {
document.getSelection().setPosition(node, node.data.length);
} else {
document.getSelection().setPosition(node, node.childNodes.length);
let codeMirrorNode = node.querySelector(".CodeMirror-line")
if (codeMirrorNode) {
setEndOfContenteditable(element)
} else {
document.getSelection().setPosition(node, node.childNodes.length);
}
}
// blink cursor to bring cursor into view
Visual.showCursor();
Expand All @@ -41,12 +46,22 @@ function createInsert() {
}
}

// From https://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity/69727327#69727327
function setEndOfContenteditable(contentEditableElement) {
let range = document.createRange();//Create a range (a range is a like the selection but invisible)
range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
let selection = window.getSelection();//get the selection object (allows you to change selection)
selection.removeAllRanges();//remove any selections already made
selection.addRange(range);//make the range you have just created the visible selection
}

self.mappings = new Trie();
self.map_node = self.mappings;
self.mappings.add(KeyboardUtils.encodeKeystroke("<Ctrl-e>"), {
annotation: "Move the cursor to the end of the line",
feature_group: 15,
code: moveCusorEOL
code: moveCursorEOL
});
self.mappings.add(KeyboardUtils.encodeKeystroke("<Ctrl-f>"), {
annotation: "Move the cursor to the beginning of the line",
Expand Down Expand Up @@ -434,7 +449,7 @@ function createInsert() {
changed = true;
}
if (changed && !keepCursor && runtime.conf.cursorAtEndOfInput && elm.nodeName !== 'SELECT') {
moveCusorEOL();
moveCursorEOL();
}
};

Expand Down
26 changes: 21 additions & 5 deletions src/content_scripts/front.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,19 @@ function createFront(insert, normal, hints, visual, browser) {
// setEditorText and setValueWithEventDispatched are experimental APIs from Brook Build of Chromium
// https://brookhong.github.io/2021/04/18/brook-build-of-chromium.html
if (elementBehindEditor.nodeName === "DIV") {
data = data.replace(/\n+$/, '');
if (typeof elementBehindEditor.setEditorText === "function") {
elementBehindEditor.setEditorText(data);
if (elementBehindEditor.className === "CodeMirror-code") {
window.getSelection().selectAllChildren(elementBehindEditor)
let dataTransfer = new DataTransfer()
dataTransfer.items.add(data, 'text/plain')
elementBehindEditor.dispatchEvent(new ClipboardEvent('paste', {clipboardData: dataTransfer}))
} else {
elementBehindEditor.innerText = data;
data = data.replace(/\n+$/, '');

if (typeof elementBehindEditor.setEditorText === "function") {
elementBehindEditor.setEditorText(data);
} else {
elementBehindEditor.innerText = data;
}
}
} else {
if (typeof elementBehindEditor.setValueWithEventDispatched === "function") {
Expand Down Expand Up @@ -284,7 +292,15 @@ function createFront(insert, normal, hints, visual, browser) {
} else {
elementBehindEditor = element;
if (elementBehindEditor.nodeName === "DIV") {
content = elementBehindEditor.innerText;
if (elementBehindEditor.className === "CodeMirror-code") {
let codeMirrorLines = elementBehindEditor.querySelectorAll(".CodeMirror-line")
content = Array.from(codeMirrorLines).map(el => el.innerText).join("\n")
// Remove the red dot (char code 8226) that CodeMirror uses to visualize the zero-width space.
content = content.replace(/\u200B/g, "")

} else {
content = elementBehindEditor.innerText;
}
} else {
content = elementBehindEditor.value;
}
Expand Down

0 comments on commit d514896

Please sign in to comment.