diff options
| author | Hsieh Chin Fan <pham@topo.tw> | 2024-10-08 00:59:37 +0800 |
|---|---|---|
| committer | Hsieh Chin Fan <pham@topo.tw> | 2024-10-08 10:37:29 +0800 |
| commit | 4f17bc1431ead015cd14d7646dd5356c589d6d1d (patch) | |
| tree | d50eecf8c20e9aa5b67b97f5d4798e21bc1bab82 | |
| parent | 01a9cd27d499ac4d12672e9c3ae9c20c5af4bcc2 (diff) | |
feat: sync selection from HTML to CodeMirror
This is for adding reference style links
| -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={{{,}}} |