diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/MenuItem.mjs | 39 | ||||
-rw-r--r-- | src/css/index.css | 5 | ||||
-rw-r--r-- | src/editor.mjs | 33 |
3 files changed, 49 insertions, 28 deletions
diff --git a/src/MenuItem.mjs b/src/MenuItem.mjs index 50afdb5..1b04d1c 100644 --- a/src/MenuItem.mjs +++ b/src/MenuItem.mjs | |||
@@ -1,3 +1,39 @@ | |||
1 | import { createGeoLink } from './dumbymap' | ||
2 | |||
3 | export class GeoLink { | ||
4 | |||
5 | constructor({ range }) { | ||
6 | this.range = range | ||
7 | } | ||
8 | |||
9 | createElement = () => { | ||
10 | const element = document.createElement('div') | ||
11 | element.className = 'menu-item-add-geolink' | ||
12 | element.innerText = "Add GeoLink" | ||
13 | element.onclick = this.addGeoLinkbyRange | ||
14 | |||
15 | return element | ||
16 | } | ||
17 | |||
18 | addGeoLinkbyRange = () => { | ||
19 | const range = this.range | ||
20 | const content = range.toString() | ||
21 | // FIXME Apply geolink only on matching sub-range | ||
22 | const match = content.match(/(^\D*[\d.]+)\D+([\d.]+)\D*$/) | ||
23 | if (!match) return false | ||
24 | |||
25 | const [x, y] = match.slice(1) | ||
26 | const anchor = document.createElement('a') | ||
27 | anchor.textContent = content | ||
28 | // FIXME apply WGS84 | ||
29 | anchor.href = `geo:${y},${x}?xy=${x},${y}` | ||
30 | |||
31 | if (createGeoLink(anchor)) { | ||
32 | range.deleteContents() | ||
33 | range.insertNode(anchor) | ||
34 | } | ||
35 | } | ||
36 | } | ||
1 | export class Suggestion { | 37 | export class Suggestion { |
2 | constructor({ text, replace }) { | 38 | constructor({ text, replace }) { |
3 | this.text = text | 39 | this.text = text |
@@ -13,7 +49,8 @@ export class Suggestion { | |||
13 | } | 49 | } |
14 | option.classList.add('container__suggestion'); | 50 | option.classList.add('container__suggestion'); |
15 | option.onmouseover = () => { | 51 | option.onmouseover = () => { |
16 | Array.from(menu.children).forEach(s => s.classList.remove('focus')) | 52 | Array.from(option.parentElement?.children ?? []) |
53 | .forEach(s => s.classList.remove('focus')) | ||
17 | option.classList.add('focus') | 54 | option.classList.add('focus') |
18 | } | 55 | } |
19 | option.onmouseout = () => { | 56 | option.onmouseout = () => { |
diff --git a/src/css/index.css b/src/css/index.css index 4737535..e4d29da 100644 --- a/src/css/index.css +++ b/src/css/index.css | |||
@@ -163,3 +163,8 @@ body { | |||
163 | } | 163 | } |
164 | } | 164 | } |
165 | } | 165 | } |
166 | |||
167 | .menu-item-add-geolink { | ||
168 | padding: 0.5rem; | ||
169 | cursor: pointer; | ||
170 | } | ||
diff --git a/src/editor.mjs b/src/editor.mjs index 32929ea..297d75a 100644 --- a/src/editor.mjs +++ b/src/editor.mjs | |||
@@ -1,8 +1,8 @@ | |||
1 | /*global EasyMDE*/ | 1 | /*global EasyMDE*/ |
2 | /*eslint no-undef: "error"*/ | 2 | /*eslint no-undef: "error"*/ |
3 | import { markdown2HTML, generateMaps, createGeoLink } from './dumbymap' | 3 | import { markdown2HTML, generateMaps } from './dumbymap' |
4 | import { defaultAliases, parseConfigsFromYaml } from 'mapclay' | 4 | import { defaultAliases, parseConfigsFromYaml } from 'mapclay' |
5 | import { Suggestion } from './MenuItem' | 5 | import { GeoLink, Suggestion } from './MenuItem' |
6 | 6 | ||
7 | // Set up Containers {{{ | 7 | // Set up Containers {{{ |
8 | 8 | ||
@@ -157,7 +157,7 @@ const debounceForMap = (() => { | |||
157 | let timer = null; | 157 | let timer = null; |
158 | 158 | ||
159 | return function(...args) { | 159 | return function(...args) { |
160 | dumbymap = generateMaps.apply(this, args) | 160 | dumbymap = generateMaps.apply(this, args) |
161 | // clearTimeout(timer); | 161 | // clearTimeout(timer); |
162 | // timer = setTimeout(() => { | 162 | // timer = setTimeout(() => { |
163 | // dumbymap = generateMaps.apply(this, args) | 163 | // dumbymap = generateMaps.apply(this, args) |
@@ -576,36 +576,15 @@ layoutObserver.observe(HtmlContainer, { | |||
576 | }); | 576 | }); |
577 | // }}} | 577 | // }}} |
578 | // ContextMenu {{{ | 578 | // ContextMenu {{{ |
579 | const addGeoLinkbyRange = (range) => { | ||
580 | const content = range.toString() | ||
581 | const match = content.match(/(^\D*[\d\.]+)\D+([\d\.]+)\D*$/) | ||
582 | // TODO add more suggestion | ||
583 | if (!match) return false | ||
584 | |||
585 | const [x, y] = match.slice(1) | ||
586 | const anchor = document.createElement('a') | ||
587 | anchor.textContent = content | ||
588 | // FIXME apply WGS84 | ||
589 | anchor.href = `geo:${y},${x}?xy=${x},${y}` | ||
590 | |||
591 | if (createGeoLink(anchor)) { | ||
592 | range.deleteContents() | ||
593 | range.insertNode(anchor) | ||
594 | } | ||
595 | |||
596 | } | ||
597 | document.oncontextmenu = (e) => { | 579 | document.oncontextmenu = (e) => { |
598 | const selection = document.getSelection() | 580 | const selection = document.getSelection() |
599 | const range = selection.getRangeAt(0) | 581 | const range = selection.getRangeAt(0) |
600 | if (!cm.hasFocus() && selection) { | 582 | if (!cm.hasFocus() && selection) { |
601 | e.preventDefault() | 583 | e.preventDefault() |
602 | menu.innerHTML = '' | 584 | menu.innerHTML = '' |
603 | menu.style.cssText = `display: block; left: ${e.clientX + 10}px; top: ${e.clientY + 5}px; width: 100px; height: 100px;` | 585 | menu.style.cssText = `display: block; left: ${e.clientX + 10}px; top: ${e.clientY + 5}px;` |
604 | menu.innerHTML = '<div style="cursor: pointer;">Create Geo-Link</div>' | 586 | const addGeoLink = new GeoLink({ range }) |
605 | menu.firstChild.onclick = () => { | 587 | menu.appendChild(addGeoLink.createElement()) |
606 | // menu.style.display = 'none' | ||
607 | addGeoLinkbyRange(range) | ||
608 | } | ||
609 | } | 588 | } |
610 | } | 589 | } |
611 | 590 | ||