diff options
-rw-r--r-- | src/editor.mjs | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/src/editor.mjs b/src/editor.mjs index d1f84a2..533ff16 100644 --- a/src/editor.mjs +++ b/src/editor.mjs | |||
@@ -404,6 +404,13 @@ const completeForCodeBlock = change => { | |||
404 | * @param {HTMLElement} menu -- menu of dumbymap | 404 | * @param {HTMLElement} menu -- menu of dumbymap |
405 | */ | 405 | */ |
406 | const menuForEditor = (event, menu) => { | 406 | const menuForEditor = (event, menu) => { |
407 | event.preventDefault() | ||
408 | |||
409 | if (cm.getSelection() && refLinks.length > 0) { | ||
410 | menu.replaceChildren() | ||
411 | menu.appendChild(menuItem.addRefLink(cm, refLinks)) | ||
412 | } | ||
413 | |||
407 | if (context.dataset.mode !== 'editing') { | 414 | if (context.dataset.mode !== 'editing') { |
408 | const switchToEditingMode = new menuItem.Item({ | 415 | const switchToEditingMode = new menuItem.Item({ |
409 | innerHTML: '<strong>EDIT</strong>', | 416 | innerHTML: '<strong>EDIT</strong>', |
@@ -439,7 +446,7 @@ const menuForEditor = (event, menu) => { | |||
439 | { line: Infinity } | 446 | { line: Infinity } |
440 | ) | 447 | ) |
441 | refLinks = getRefLinks() | 448 | refLinks = getRefLinks() |
442 | map.renderer.addMarker({xy: [Number(x), Number(y)], title: `${map.id}@${x},${y}`, type: 'circle'}) | 449 | map.renderer.addMarker({ xy: [Number(x), Number(y)], title: `${map.id}@${x},${y}`, type: 'circle' }) |
443 | } | 450 | } |
444 | }) | 451 | }) |
445 | menu.insertBefore(item, menu.firstChild) | 452 | menu.insertBefore(item, menu.firstChild) |
@@ -1001,4 +1008,52 @@ cm.getWrapperElement().oncontextmenu = e => { | |||
1001 | } | 1008 | } |
1002 | } | 1009 | } |
1003 | 1010 | ||
1011 | /** HACK Sync selection from HTML to CodeMirror */ | ||
1012 | document.addEventListener("selectionchange", () => { | ||
1013 | if (cm.hasFocus()) { | ||
1014 | return | ||
1015 | } | ||
1016 | |||
1017 | const selection = document.getSelection() | ||
1018 | if (selection.type === 'Range') { | ||
1019 | const content = selection.getRangeAt(0).toString() | ||
1020 | const parentWithSourceLine = selection.anchorNode.parentElement.closest('.source-line') | ||
1021 | const lineStart = Number(parentWithSourceLine?.dataset?.sourceLine ?? NaN) | ||
1022 | const lineEnd = Number(parentWithSourceLine?.nextSibling?.dataset?.sourceLine ?? NaN) | ||
1023 | // TODO Also return when range contains anchor element | ||
1024 | if (content.includes('\n') || isNaN(lineStart)) { | ||
1025 | cm.setSelection(cm.getCursor()) | ||
1026 | return | ||
1027 | } | ||
1028 | |||
1029 | let texts = [content] | ||
1030 | let sibling = selection.anchorNode.previousSibling | ||
1031 | while (sibling) { | ||
1032 | texts.push(sibling.textContent) | ||
1033 | sibling = sibling.previousSibling | ||
1034 | } | ||
1035 | |||
1036 | const anchor = { line: lineStart, ch: 0 } | ||
1037 | |||
1038 | texts | ||
1039 | .filter(t => t && t !== '\n') | ||
1040 | .map(t => t.replace('\n', '')) | ||
1041 | .reverse() | ||
1042 | .forEach(text => { | ||
1043 | let index = cm.getLine(anchor.line).indexOf(text, anchor.ch) | ||
1044 | while (index === -1) { | ||
1045 | anchor.line += 1 | ||
1046 | anchor.ch = 0 | ||
1047 | if (anchor.line >= lineEnd) { | ||
1048 | cm.setSelection(cm.setCursor()) | ||
1049 | return | ||
1050 | } | ||
1051 | index = cm.getLine(anchor.line).indexOf(text) | ||
1052 | } | ||
1053 | anchor.ch = index + text.length | ||
1054 | }) | ||
1055 | |||
1056 | cm.setSelection({ ...anchor, ch: anchor.ch - content.length }, anchor) | ||
1057 | } | ||
1058 | }); | ||
1004 | // vim: sw=2 ts=2 foldmethod=marker foldmarker={{{,}}} | 1059 | // vim: sw=2 ts=2 foldmethod=marker foldmarker={{{,}}} |