diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dumbyUtils.mjs | 40 | ||||
-rw-r--r-- | src/editor.mjs | 53 |
2 files changed, 58 insertions, 35 deletions
diff --git a/src/dumbyUtils.mjs b/src/dumbyUtils.mjs index 95bb3dd..be45139 100644 --- a/src/dumbyUtils.mjs +++ b/src/dumbyUtils.mjs | |||
@@ -6,7 +6,7 @@ import { insideWindow, insideParent } from './utils' | |||
6 | * | 6 | * |
7 | * @param {Boolean} reverse -- focus previous map | 7 | * @param {Boolean} reverse -- focus previous map |
8 | */ | 8 | */ |
9 | export function focusNextMap (reverse = false) { | 9 | export function focusNextMap(reverse = false) { |
10 | const renderedList = this.utils.renderedMaps() | 10 | const renderedList = this.utils.renderedMaps() |
11 | const index = renderedList.findIndex(e => e.classList.contains('focus')) | 11 | const index = renderedList.findIndex(e => e.classList.contains('focus')) |
12 | const nextIndex = (index + (reverse ? -1 : 1)) % renderedList.length | 12 | const nextIndex = (index + (reverse ? -1 : 1)) % renderedList.length |
@@ -21,7 +21,7 @@ export function focusNextMap (reverse = false) { | |||
21 | * | 21 | * |
22 | * @param {Boolean} reverse -- focus previous block | 22 | * @param {Boolean} reverse -- focus previous block |
23 | */ | 23 | */ |
24 | export function focusNextBlock (reverse = false) { | 24 | export function focusNextBlock(reverse = false) { |
25 | const blocks = this.blocks.filter(b => | 25 | const blocks = this.blocks.filter(b => |
26 | b.checkVisibility({ | 26 | b.checkVisibility({ |
27 | contentVisibilityAuto: true, | 27 | contentVisibilityAuto: true, |
@@ -56,7 +56,7 @@ export const scrollToBlock = block => { | |||
56 | /** | 56 | /** |
57 | * focusDelay. Delay of throttle, value changes by cases | 57 | * focusDelay. Delay of throttle, value changes by cases |
58 | */ | 58 | */ |
59 | export function focusDelay () { | 59 | export function focusDelay() { |
60 | return window.window.getComputedStyle(this.showcase).display === 'none' ? 50 : 300 | 60 | return window.window.getComputedStyle(this.showcase).display === 'none' ? 50 : 300 |
61 | } | 61 | } |
62 | 62 | ||
@@ -65,7 +65,7 @@ export function focusDelay () { | |||
65 | * | 65 | * |
66 | * @param {Boolean} reverse -- Switch to previous one | 66 | * @param {Boolean} reverse -- Switch to previous one |
67 | */ | 67 | */ |
68 | export function switchToNextLayout (reverse = false) { | 68 | export function switchToNextLayout(reverse = false) { |
69 | const layouts = this.layouts | 69 | const layouts = this.layouts |
70 | const currentLayoutName = this.container.getAttribute('data-layout') | 70 | const currentLayoutName = this.container.getAttribute('data-layout') |
71 | const currentIndex = layouts.map(l => l.name).indexOf(currentLayoutName) | 71 | const currentIndex = layouts.map(l => l.name).indexOf(currentLayoutName) |
@@ -81,7 +81,7 @@ export function switchToNextLayout (reverse = false) { | |||
81 | /** | 81 | /** |
82 | * removeBlockFocus. | 82 | * removeBlockFocus. |
83 | */ | 83 | */ |
84 | export function removeBlockFocus () { | 84 | export function removeBlockFocus() { |
85 | this.blocks.forEach(b => b.classList.remove('focus')) | 85 | this.blocks.forEach(b => b.classList.remove('focus')) |
86 | } | 86 | } |
87 | 87 | ||
@@ -243,3 +243,33 @@ const isAnchorVisible = anchor => { | |||
243 | const mapContainer = anchor.closest('.mapclay') | 243 | const mapContainer = anchor.closest('.mapclay') |
244 | return insideWindow(anchor) && insideParent(anchor, mapContainer) | 244 | return insideWindow(anchor) && insideParent(anchor, mapContainer) |
245 | } | 245 | } |
246 | |||
247 | export const addAnchorByEvent = ({ | ||
248 | event, | ||
249 | map, | ||
250 | validateAnchorName = () => true | ||
251 | }) => { | ||
252 | const rect = map.getBoundingClientRect() | ||
253 | const [x, y] = map.renderer | ||
254 | .unproject([event.x - rect.left, event.y - rect.top]) | ||
255 | .map(coord => Number(coord.toFixed(7))) | ||
256 | |||
257 | let prompt | ||
258 | let anchorName | ||
259 | |||
260 | do { | ||
261 | prompt = prompt ? 'Anchor name exists' : 'Name this anchor' | ||
262 | anchorName = window.prompt(prompt, `${x}, ${y}`) | ||
263 | } | ||
264 | while (anchorName !== null && !validateAnchorName(anchorName)) | ||
265 | if (anchorName === null) return | ||
266 | |||
267 | const link = `geo:${y},${x}?xy=${x},${y}&id=${map.id} "${anchorName}"` | ||
268 | map.renderer.addMarker({ | ||
269 | xy: [x, y], | ||
270 | title: `${map.id}@${x}, ${y}`, | ||
271 | type: 'circle', | ||
272 | }) | ||
273 | |||
274 | return { ref: anchorName, link } | ||
275 | } | ||
diff --git a/src/editor.mjs b/src/editor.mjs index 499d42b..1c444eb 100644 --- a/src/editor.mjs +++ b/src/editor.mjs | |||
@@ -4,6 +4,7 @@ import { markdown2HTML, generateMaps } from './dumbymap' | |||
4 | import { defaultAliases, parseConfigsFromYaml } from 'mapclay' | 4 | import { defaultAliases, parseConfigsFromYaml } from 'mapclay' |
5 | import * as menuItem from './MenuItem' | 5 | import * as menuItem from './MenuItem' |
6 | import { shiftByWindow } from './utils.mjs' | 6 | import { shiftByWindow } from './utils.mjs' |
7 | import { addAnchorByEvent } from './dumbyUtils.mjs' | ||
7 | 8 | ||
8 | // Set up Containers {{{ | 9 | // Set up Containers {{{ |
9 | 10 | ||
@@ -47,7 +48,7 @@ const toggleEditing = () => { | |||
47 | // Content values for editor | 48 | // Content values for editor |
48 | 49 | ||
49 | const defaultContent = | 50 | const defaultContent = |
50 | `<br> | 51 | `<br> |
51 | 52 | ||
52 | > <big>Hello My Friend! This is DumbyMap!</big> | 53 | > <big>Hello My Friend! This is DumbyMap!</big> |
53 | 54 | ||
@@ -441,30 +442,21 @@ const menuForEditor = (event, menu) => { | |||
441 | if (map) { | 442 | if (map) { |
442 | const item = new menuItem.Item({ | 443 | const item = new menuItem.Item({ |
443 | text: 'Add Anchor', | 444 | text: 'Add Anchor', |
444 | onclick: () => { | 445 | onclick: (event) => { |
445 | const rect = map.getBoundingClientRect() | 446 | const validateAnchorName = anchorName => |
446 | const [x, y] = map.renderer | 447 | !refLinks.find(obj => obj.ref === anchorName) |
447 | .unproject([event.x - rect.left, event.y - rect.top]) | 448 | const { ref, link } = addAnchorByEvent({ |
448 | .map(coord => coord.toFixed(7)) | 449 | event, |
449 | 450 | map, | |
450 | let prompt | 451 | validateAnchorName |
451 | let anchorName | 452 | }) |
452 | |||
453 | do { | ||
454 | prompt = prompt ? 'Anchor name exists' : 'Name this anchor' | ||
455 | anchorName = window.prompt(prompt, `${x}, ${y}`) | ||
456 | } | ||
457 | while (anchorName !== null && refLinks.find(({ ref }) => ref === anchorName)) | ||
458 | if (anchorName === null) return | ||
459 | 453 | ||
460 | const link = `geo:${y},${x}?xy=${x},${y}&id=${map.id} "${anchorName}"` | 454 | let refLinkString = `\n[${ref}]: ${link}` |
461 | const lastLineIsRefLink = cm.getLine(cm.lastLine()).match(refLinkPattern) | 455 | const lastLineIsRefLink = cm.getLine(cm.lastLine()).match(refLinkPattern) |
462 | cm.replaceRange( | 456 | if (lastLineIsRefLink) refLinkString = '\n' + refLinkString |
463 | `${lastLineIsRefLink ? '' : '\n'}\n[${anchorName}]: ${link}`, | 457 | cm.replaceRange(refLinkString, { line: Infinity }) |
464 | { line: Infinity } | 458 | |
465 | ) | 459 | refLinks.push({ ref, link }) |
466 | refLinks = getRefLinks() | ||
467 | map.renderer.addMarker({ xy: [Number(x), Number(y)], title: `${map.id}@${x},${y}`, type: 'circle' }) | ||
468 | } | 460 | } |
469 | }) | 461 | }) |
470 | menu.insertBefore(item, menu.firstChild) | 462 | menu.insertBefore(item, menu.firstChild) |
@@ -802,13 +794,13 @@ const getSuggestions = anchor => { | |||
802 | return rendererSuggestions.length === 0 | 794 | return rendererSuggestions.length === 0 |
803 | ? [] | 795 | ? [] |
804 | : [ | 796 | : [ |
805 | ...rendererSuggestions, | 797 | ...rendererSuggestions, |
806 | new menuItem.Item({ | 798 | new menuItem.Item({ |
807 | innerHTML: '<a href="https://github.com/outdoorsafetylab/mapclay#renderer" class="external" style="display: block;">More...</a>', | 799 | innerHTML: '<a href="https://github.com/outdoorsafetylab/mapclay#renderer" class="external" style="display: block;">More...</a>', |
808 | className: ['suggestion'], | 800 | className: ['suggestion'], |
809 | onclick: () => window.open('https://github.com/outdoorsafetylab/mapclay#renderer', '_blank') | 801 | onclick: () => window.open('https://github.com/outdoorsafetylab/mapclay#renderer', '_blank') |
810 | }) | 802 | }) |
811 | ] | 803 | ] |
812 | } | 804 | } |
813 | return [] | 805 | return [] |
814 | } | 806 | } |
@@ -1076,4 +1068,5 @@ document.addEventListener('selectionchange', () => { | |||
1076 | cm.setSelection({ ...anchor, ch: anchor.ch - content.length }, anchor) | 1068 | cm.setSelection({ ...anchor, ch: anchor.ch - content.length }, anchor) |
1077 | } | 1069 | } |
1078 | }) | 1070 | }) |
1071 | |||
1079 | // vim: sw=2 ts=2 foldmethod=marker foldmarker={{{,}}} | 1072 | // vim: sw=2 ts=2 foldmethod=marker foldmarker={{{,}}} |