aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHsieh Chin Fan <pham@topo.tw>2024-10-30 17:00:45 +0800
committerHsieh Chin Fan <pham@topo.tw>2024-10-31 11:31:00 +0800
commit6a468847939c8983b7e2ad2a0604d66beebdb94f (patch)
tree9201ab9fca489af7843de28768cc97e606c5f41f
parentcba9e807dd39f3c03a66c554c092b0b2c094ba38 (diff)
refactor: remove custom elements
REASON: apply custom elements in content script may change globalThis which is not equal to window. This makes type check in maplibregl always fails!
-rw-r--r--src/MenuItem.mjs223
-rw-r--r--src/dumbymap.mjs6
-rw-r--r--src/editor.mjs14
3 files changed, 112 insertions, 131 deletions
diff --git a/src/MenuItem.mjs b/src/MenuItem.mjs
index e560b39..103f43e 100644
--- a/src/MenuItem.mjs
+++ b/src/MenuItem.mjs
@@ -13,13 +13,7 @@ import { parseConfigsFromYaml } from 'mapclay'
13 */ 13 */
14 14
15/** 15/**
16 * Basic Element for menu item 16 * Creates a Item instance
17 *
18 * @extends {window.HTMLDivElement}
19 */
20export class Item extends window.HTMLDivElement {
21 /**
22 * Creates a new Item instance
23 * 17 *
24 * @param {Object} options - The options for the item 18 * @param {Object} options - The options for the item
25 * @param {string} [options.text] - The text content of the item 19 * @param {string} [options.text] - The text content of the item
@@ -29,74 +23,70 @@ export class Item extends window.HTMLDivElement {
29 * @param {string} [options.style] - The CSS style string 23 * @param {string} [options.style] - The CSS style string
30 * @param {string[]} [options.className] - Additional CSS classes 24 * @param {string[]} [options.className] - Additional CSS classes
31 */ 25 */
32 constructor ({ id, text, innerHTML, title, onclick, style, className }) { 26export const Item = ({
33 super() 27 id,
34 if (id) this.id = id 28 text,
35 if (title) this.title = title 29 innerHTML,
36 this.innerHTML = innerHTML ?? text 30 title,
37 this.onclick = onclick 31 onclick,
38 this.style.cssText = style 32 style,
39 this.classList.add('menu-item') 33 className,
40 className?.forEach(c => this.classList.add(c)) 34}) => {
41 35 const menuItem = document.createElement('div')
42 this.onmouseover = () => { 36 if (id) menuItem.id = id
43 this.parentElement 37 if (title) menuItem.title = title
44 .querySelectorAll('.sub-menu') 38 menuItem.innerHTML = innerHTML ?? text
45 .forEach(sub => sub.remove()) 39 menuItem.onclick = onclick
46 } 40 menuItem.style.cssText = style
41 menuItem.classList.add('menu-item')
42 className?.forEach(c => menuItem.classList.add(c))
43
44 menuItem.onmouseover = () => {
45 menuItem.parentElement
46 .querySelectorAll('.sub-menu')
47 .forEach(sub => sub.remove())
47 } 48 }
48} 49 return menuItem
49if (!window.customElements.get('dumby-menu-item')) {
50 window.customElements.define('dumby-menu-item', Item, { extends: 'div' })
51} 50}
52 51
53/** 52/**
54 * Basic Element for menu item that generates a submenu on hover 53 * Creates a new menu item that generates a submenu on hover
55 * 54 *
56 * @extends {window.HTMLDivElement} 55 * @param {Object} options - The options for the folder
56 * @param {string} [options.text] - The text content of the folder
57 * @param {string} [options.innerHTML] - The HTML content of the folder
58 * @param {Item[]} options.items - The submenu items
57 */ 59 */
58export class Folder extends window.HTMLDivElement { 60export const Folder = ({ id, text, innerHTML, items, style }) => {
59 /** 61 const folder = document.createElement('div')
60 * Creates a new Folder instance 62 if (id) folder.id = id
61 * 63 folder.innerHTML = innerHTML ?? text
62 * @param {Object} options - The options for the folder 64 folder.classList.add('folder', 'menu-item')
63 * @param {string} [options.text] - The text content of the folder 65 folder.items = items
64 * @param {string} [options.innerHTML] - The HTML content of the folder 66 folder.onmouseover = () => {
65 * @param {Item[]} options.items - The submenu items 67 if (folder.querySelector('.sub-menu')) return
66 */ 68 // Prepare submenu
67 constructor ({ id, text, innerHTML, items, style }) { 69 const submenu = document.createElement('div')
68 super() 70 submenu.className = 'sub-menu'
69 if (id) this.id = id 71 const offset = folder.items.length > 1 ? '-20px' : '0px'
70 this.innerHTML = innerHTML ?? text 72 submenu.style.cssText = `${style ?? ''}position: absolute; left: 105%; top: ${offset};`
71 this.classList.add('folder', 'menu-item') 73 folder.items.forEach(item => submenu.appendChild(item))
72 this.items = items 74 submenu.onmouseleave = () => {
73 this.onmouseover = () => { 75 if (submenu.querySelectorAll('.sub-menu').length > 0) return
74 if (this.querySelector('.sub-menu')) return 76 submenu.remove()
75 // Prepare submenu
76 const submenu = document.createElement('div')
77 submenu.className = 'sub-menu'
78 const offset = this.items.length > 1 ? '-20px' : '0px'
79 submenu.style.cssText = `${style ?? ''}position: absolute; left: 105%; top: ${offset};`
80 this.items.forEach(item => submenu.appendChild(item))
81 submenu.onmouseleave = () => {
82 if (submenu.querySelectorAll('.sub-menu').length > 0) return
83 submenu.remove()
84 }
85
86 // hover effect
87 this.parentElement
88 .querySelectorAll('.sub-menu')
89 .forEach(sub => sub.remove())
90 this.appendChild(submenu)
91 shiftByWindow(submenu)
92 } 77 }
78
79 // hover effect
80 folder.parentElement
81 .querySelectorAll('.sub-menu')
82 .forEach(sub => sub.remove())
83 folder.appendChild(submenu)
84 shiftByWindow(submenu)
93 } 85 }
94} 86 return folder
95if (!window.customElements.get('menu-folder')) {
96 window.customElements.define('menu-folder', Folder, { extends: 'div' })
97} 87}
98 88
99export const simplePlaceholder = (text) => new Item({ 89export const simplePlaceholder = (text) => Item({
100 text, 90 text,
101 style: 'width: fit-content; margin: 0 auto; color: gray; pointer-events: none; font-size: 0.8rem; line-height: 1; font-weight: bolder;', 91 style: 'width: fit-content; margin: 0 auto; color: gray; pointer-events: none; font-size: 0.8rem; line-height: 1; font-weight: bolder;',
102}) 92})
@@ -109,11 +99,11 @@ export const simplePlaceholder = (text) => new Item({
109 * @returns {Folder} A Folder instance for picking a map 99 * @returns {Folder} A Folder instance for picking a map
110 */ 100 */
111export const pickMapItem = ({ utils }) => 101export const pickMapItem = ({ utils }) =>
112 new Folder({ 102 Folder({
113 innerHTML: '<span>Maps<span><span class="info">(Tab)</span>', 103 innerHTML: '<span>Maps<span><span class="info">(Tab)</span>',
114 items: utils.renderedMaps().map( 104 items: utils.renderedMaps().map(
115 map => 105 map =>
116 new Item({ 106 Item({
117 text: map.id, 107 text: map.id,
118 onclick: () => { 108 onclick: () => {
119 map.classList.add('focus') 109 map.classList.add('focus')
@@ -130,7 +120,7 @@ export const pickMapItem = ({ utils }) =>
130 * @param {Function[]} options.utils 120 * @param {Function[]} options.utils
131 */ 121 */
132export const pickBlockItem = ({ blocks, utils }) => 122export const pickBlockItem = ({ blocks, utils }) =>
133 new Folder({ 123 Folder({
134 innerHTML: '<span>Blocks<span><span class="info">(n/p)</span>', 124 innerHTML: '<span>Blocks<span><span class="info">(n/p)</span>',
135 items: blocks.map( 125 items: blocks.map(
136 (block, index) => { 126 (block, index) => {
@@ -139,7 +129,7 @@ export const pickBlockItem = ({ blocks, utils }) =>
139 ?.textContent.substring(0, 15) 129 ?.textContent.substring(0, 15)
140 ?.concat(' ', '... ') ?? '' 130 ?.concat(' ', '... ') ?? ''
141 131
142 return new Item({ 132 return Item({
143 className: ['keep-menu', focus ? 'checked' : 'unchecked'], 133 className: ['keep-menu', focus ? 'checked' : 'unchecked'],
144 innerHTML: 134 innerHTML:
145 `<strong>(${index})</strong><span style='display: inline-block; margin-inline: 1.2em;'>${preview}</span>`, 135 `<strong>(${index})</strong><span style='display: inline-block; margin-inline: 1.2em;'>${preview}</span>`,
@@ -168,17 +158,17 @@ export const pickBlockItem = ({ blocks, utils }) =>
168 * @param {String[]} options.layouts 158 * @param {String[]} options.layouts
169 */ 159 */
170export const pickLayoutItem = ({ container, layouts }) => 160export const pickLayoutItem = ({ container, layouts }) =>
171 new Folder({ 161 Folder({
172 innerHTML: '<span>Layouts<span><span class="info">(x)</span>', 162 innerHTML: '<span>Layouts<span><span class="info">(x)</span>',
173 items: [ 163 items: [
174 ...layouts.map( 164 ...layouts.map(
175 layout => 165 layout =>
176 new Item({ 166 Item({
177 text: layout.name, 167 text: layout.name,
178 onclick: () => container.setAttribute('data-layout', layout.name), 168 onclick: () => container.setAttribute('data-layout', layout.name),
179 }), 169 }),
180 ), 170 ),
181 new Item({ 171 Item({
182 innerHTML: '<a href="https://github.com/outdoorsafetylab/dumbymap#layouts" class="external" style="display: block; padding: 0.5rem;">More...</a>', 172 innerHTML: '<a href="https://github.com/outdoorsafetylab/dumbymap#layouts" class="external" style="display: block; padding: 0.5rem;">More...</a>',
183 style: 'padding: 0;', 173 style: 'padding: 0;',
184 }), 174 }),
@@ -192,7 +182,7 @@ export const pickLayoutItem = ({ container, layouts }) =>
192 * @param {Range} range 182 * @param {Range} range
193 */ 183 */
194export const addGeoLink = ({ utils }, range) => 184export const addGeoLink = ({ utils }, range) =>
195 new Item({ 185 Item({
196 text: 'Add GeoLink', 186 text: 'Add GeoLink',
197 onclick: () => { 187 onclick: () => {
198 const content = range.toString() 188 const content = range.toString()
@@ -215,44 +205,35 @@ export const addGeoLink = ({ utils }, range) =>
215 }) 205 })
216 206
217/** 207/**
218 * Suggestion. Menu Item for editor suggestion 208 * Suggestion. Menu Item for editor suggestion.
219 *
220 * @extends {Item}
221 */
222export class Suggestion extends Item {
223 /**
224 * constructor.
225 * 209 *
226 * @param {String} options.text 210 * @param {String} options.text
227 * @param {String} options.replace - new text content 211 * @param {String} options.replace - new text content
228 * @param {CodeMirror} options.cm 212 * @param {CodeMirror} options.cm
229 */ 213 */
230 constructor ({ text, replace, cm }) { 214export const Suggestion = ({ text, replace, cm }) => {
231 super({ text }) 215 const suggestion = Item({ text })
232 this.replace = replace 216 suggestion.replace = replace
233 this.classList.add('suggestion') 217 suggestion.classList.add('suggestion')
234 218
235 this.onmouseover = () => { 219 suggestion.onmouseover = () => {
236 Array.from(this.parentElement?.children)?.forEach(s => 220 Array.from(suggestion.parentElement?.children)?.forEach(s =>
237 s.classList.remove('focus'), 221 s.classList.remove('focus'),
238 ) 222 )
239 this.classList.add('focus') 223 suggestion.classList.add('focus')
240 }
241 this.onmouseout = () => {
242 this.classList.remove('focus')
243 }
244 this.onclick = () => {
245 const anchor = cm.getCursor()
246 cm.setSelection(anchor, { ...anchor, ch: 0 })
247 cm.replaceSelection(this.replace)
248 cm.focus()
249 const newAnchor = { ...anchor, ch: this.replace.length }
250 cm.setCursor(newAnchor)
251 }
252 } 224 }
253} 225 suggestion.onmouseout = () => {
254if (!window.customElements.get('menu-item-suggestion')) { 226 suggestion.classList.remove('focus')
255 window.customElements.define('menu-item-suggestion', Suggestion, { extends: 'div' }) 227 }
228 suggestion.onclick = () => {
229 const anchor = cm.getCursor()
230 cm.setSelection(anchor, { ...anchor, ch: 0 })
231 cm.replaceSelection(suggestion.replace)
232 cm.focus()
233 const newAnchor = { ...anchor, ch: suggestion.replace.length }
234 cm.setCursor(newAnchor)
235 }
236 return suggestion
256} 237}
257 238
258/** 239/**
@@ -263,7 +244,7 @@ if (!window.customElements.get('menu-item-suggestion')) {
263 * @param {HTMLElement} map - Rendered map element 244 * @param {HTMLElement} map - Rendered map element
264 */ 245 */
265export const renderResults = ({ modal, modalContent }, map) => 246export const renderResults = ({ modal, modalContent }, map) =>
266 new Item({ 247 Item({
267 text: 'Render Results', 248 text: 'Render Results',
268 onclick: () => { 249 onclick: () => {
269 modal.open() 250 modal.open()
@@ -365,7 +346,7 @@ function printObject (obj, parentElement, name = null) {
365 * @param {HTMLElement} block 346 * @param {HTMLElement} block
366 */ 347 */
367export const toggleBlockFocus = block => 348export const toggleBlockFocus = block =>
368 new Item({ 349 Item({
369 text: 'Toggle Focus', 350 text: 'Toggle Focus',
370 onclick: () => block.classList.toggle('focus'), 351 onclick: () => block.classList.toggle('focus'),
371 }) 352 })
@@ -376,7 +357,7 @@ export const toggleBlockFocus = block =>
376 * @param {HTMLElement} map 357 * @param {HTMLElement} map
377 */ 358 */
378export const toggleMapFocus = map => 359export const toggleMapFocus = map =>
379 new Item({ 360 Item({
380 text: 'Toggle Focus', 361 text: 'Toggle Focus',
381 onclick: () => { 362 onclick: () => {
382 if (map.classList.toggle('focus')) { 363 if (map.classList.toggle('focus')) {
@@ -392,7 +373,7 @@ export const toggleMapFocus = map =>
392 * @param {Number[]} xy - pixel of window 373 * @param {Number[]} xy - pixel of window
393 */ 374 */
394export const getCoordinatesByPixels = (map, xy) => 375export const getCoordinatesByPixels = (map, xy) =>
395 new Item({ 376 Item({
396 text: 'Get Coordinates', 377 text: 'Get Coordinates',
397 onclick: () => { 378 onclick: () => {
398 const [x, y] = map.renderer.unproject(xy) 379 const [x, y] = map.renderer.unproject(xy)
@@ -408,7 +389,7 @@ export const getCoordinatesByPixels = (map, xy) =>
408 * @param {HTMLElement} map 389 * @param {HTMLElement} map
409 */ 390 */
410export const restoreCamera = map => 391export const restoreCamera = map =>
411 new Item({ 392 Item({
412 text: 'Restore Camera', 393 text: 'Restore Camera',
413 onclick: () => map.renderer.restoreCamera(), 394 onclick: () => map.renderer.restoreCamera(),
414 }) 395 })
@@ -420,14 +401,14 @@ export const restoreCamera = map =>
420 * @param {RefLink[]} refLinks 401 * @param {RefLink[]} refLinks
421 */ 402 */
422export const addRefLink = (cm, refLinks) => 403export const addRefLink = (cm, refLinks) =>
423 new Folder({ 404 Folder({
424 text: 'Add Link', 405 text: 'Add Link',
425 items: refLinks.map(refLink => { 406 items: refLinks.map(refLink => {
426 let text = refLink.ref 407 let text = refLink.ref
427 if (refLink.link.startsWith('geo:')) text = `@ ${text}` 408 if (refLink.link.startsWith('geo:')) text = `@ ${text}`
428 if (refLink.title?.match(/^=>/)) text = `=> ${text}` 409 if (refLink.title?.match(/^=>/)) text = `=> ${text}`
429 410
430 return new Item({ 411 return Item({
431 text, 412 text,
432 title: refLink.link, 413 title: refLink.link,
433 onclick: () => { 414 onclick: () => {
@@ -451,7 +432,7 @@ export const addRefLink = (cm, refLinks) =>
451 */ 432 */
452export const setGeoLinkTypeItem = ({ link, type, ...others }) => { 433export const setGeoLinkTypeItem = ({ link, type, ...others }) => {
453 const params = new URLSearchParams(link.search) 434 const params = new URLSearchParams(link.search)
454 return new Item({ 435 return Item({
455 ...others, 436 ...others,
456 className: ['keep-menu'], 437 className: ['keep-menu'],
457 onclick: () => { 438 onclick: () => {
@@ -470,7 +451,7 @@ export const setGeoLinkTypeItem = ({ link, type, ...others }) => {
470 * 451 *
471 * @param {HTMLAnchorElement} link 452 * @param {HTMLAnchorElement} link
472 */ 453 */
473export const setGeoLinkType = (link) => new Folder({ 454export const setGeoLinkType = (link) => Folder({
474 text: 'Marker Type', 455 text: 'Marker Type',
475 style: 'min-width: unset; display: grid; grid-template-columns: repeat(5, 1fr);', 456 style: 'min-width: unset; display: grid; grid-template-columns: repeat(5, 1fr);',
476 items: Object.entries(markers) 457 items: Object.entries(markers)
@@ -491,10 +472,10 @@ export const setGeoLinkType = (link) => new Folder({
491 * 472 *
492 * @param {GeoLink | DocLink} link 473 * @param {GeoLink | DocLink} link
493 */ 474 */
494export const setLeaderLineType = (link) => new Folder({ 475export const setLeaderLineType = (link) => Folder({
495 text: 'Line Type', 476 text: 'Line Type',
496 items: ['magnet', 'straight', 'grid', 'fluid'] 477 items: ['magnet', 'straight', 'grid', 'fluid']
497 .map(path => new Item({ 478 .map(path => Item({
498 text: path, 479 text: path,
499 className: ['keep-menu'], 480 className: ['keep-menu'],
500 onclick: () => { 481 onclick: () => {
@@ -519,7 +500,7 @@ export const addMarker = ({
519 point, 500 point,
520 isNameValid = () => true, 501 isNameValid = () => true,
521 callback = null, 502 callback = null,
522}) => new Item({ 503}) => Item({
523 text: 'Add Marker', 504 text: 'Add Marker',
524 onclick: () => { 505 onclick: () => {
525 let markerName 506 let markerName
@@ -538,7 +519,7 @@ export const addMarker = ({
538 * 519 *
539 * @param {HTMLElement} map 520 * @param {HTMLElement} map
540 */ 521 */
541export const editMapByRawText = (map) => new Item({ 522export const editMapByRawText = (map) => Item({
542 text: 'Edit by Raw Text', 523 text: 'Edit by Raw Text',
543 onclick: () => { 524 onclick: () => {
544 const container = map.closest('.map-container') 525 const container = map.closest('.map-container')
@@ -571,12 +552,12 @@ export const editMapByRawText = (map) => new Item({
571export const editMap = (map, dumbymap) => { 552export const editMap = (map, dumbymap) => {
572 const options = Object.entries(dumbymap.aliases) 553 const options = Object.entries(dumbymap.aliases)
573 .map(([option, aliases]) => 554 .map(([option, aliases]) =>
574 new Folder({ 555 Folder({
575 text: option, 556 text: option,
576 items: Object.entries(aliases) 557 items: Object.entries(aliases)
577 .map(([alias, value]) => { 558 .map(([alias, value]) => {
578 const aliasValue = value.value ?? value 559 const aliasValue = value.value ?? value
579 return new Item({ 560 return Item({
580 innerHTML: `<div>${alias}</div><div style="padding-left: 20px; color: gray; font-size: 1rem";">${aliasValue}</div>`, 561 innerHTML: `<div>${alias}</div><div style="padding-left: 20px; color: gray; font-size: 1rem";">${aliasValue}</div>`,
581 style: 'display: flex; justify-content: space-between; max-width: 20rem;', 562 style: 'display: flex; justify-content: space-between; max-width: 20rem;',
582 onclick: () => { 563 onclick: () => {
@@ -596,7 +577,7 @@ export const editMap = (map, dumbymap) => {
596 }), 577 }),
597 }), 578 }),
598 ) 579 )
599 return new Folder({ 580 return Folder({
600 text: 'Edit Map', 581 text: 'Edit Map',
601 style: 'overflow: visible;', 582 style: 'overflow: visible;',
602 items: [ 583 items: [
diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs
index 1509c04..7fbf372 100644
--- a/src/dumbymap.mjs
+++ b/src/dumbymap.mjs
@@ -561,7 +561,7 @@ export const generateMaps = (container, {
561 /** Menu Item for editing map */ 561 /** Menu Item for editing map */
562 const mapEditor = e.target.closest('.edit-map') 562 const mapEditor = e.target.closest('.edit-map')
563 if (mapEditor) { 563 if (mapEditor) {
564 menu.appendChild(new menuItem.Item({ 564 menu.appendChild(menuItem.Item({
565 text: 'Finish Editig', 565 text: 'Finish Editig',
566 onclick: () => mapEditor.blur(), 566 onclick: () => mapEditor.blur(),
567 })) 567 }))
@@ -572,7 +572,7 @@ export const generateMaps = (container, {
572 const geoLink = e.target.closest('.geolink') 572 const geoLink = e.target.closest('.geolink')
573 if (geoLink) { 573 if (geoLink) {
574 if (geoLink.classList.contains('from-text')) { 574 if (geoLink.classList.contains('from-text')) {
575 menu.appendChild(new menuItem.Item({ 575 menu.appendChild(menuItem.Item({
576 innerHTML: '<strong style="color: red;">DELETE</strong>', 576 innerHTML: '<strong style="color: red;">DELETE</strong>',
577 onclick: () => { 577 onclick: () => {
578 getMarkersFromMaps(geoLink) 578 getMarkersFromMaps(geoLink)
@@ -601,7 +601,7 @@ export const generateMaps = (container, {
601 601
602 if (map.dataset.render === 'fulfilled') { 602 if (map.dataset.render === 'fulfilled') {
603 menu.appendChild(menuItem.toggleMapFocus(map)) 603 menu.appendChild(menuItem.toggleMapFocus(map))
604 menu.appendChild(new menuItem.Folder({ 604 menu.appendChild(menuItem.Folder({
605 text: 'Actions', 605 text: 'Actions',
606 items: [ 606 items: [
607 menuItem.getCoordinatesByPixels(map, [x, y]), 607 menuItem.getCoordinatesByPixels(map, [x, y]),
diff --git a/src/editor.mjs b/src/editor.mjs
index f7b9c65..8d22918 100644
--- a/src/editor.mjs
+++ b/src/editor.mjs
@@ -434,7 +434,7 @@ function menuForEditor (event, menu) {
434 } 434 }
435 435
436 if (context.dataset.mode !== 'editing') { 436 if (context.dataset.mode !== 'editing') {
437 const switchToEditingMode = new menuItem.Item({ 437 const switchToEditingMode = menuItem.Item({
438 innerHTML: '<strong>EDIT</strong>', 438 innerHTML: '<strong>EDIT</strong>',
439 onclick: () => (context.dataset.mode = 'editing'), 439 onclick: () => (context.dataset.mode = 'editing'),
440 }) 440 })
@@ -443,7 +443,7 @@ function menuForEditor (event, menu) {
443 443
444 // const map = event.target.closest('.mapclay') 444 // const map = event.target.closest('.mapclay')
445 // if (map) { 445 // if (map) {
446 // const item = new menuItem.Item({ 446 // const item = menuItem.Item({
447 // text: 'Add Anchor', 447 // text: 'Add Anchor',
448 // onclick: () => { 448 // onclick: () => {
449 // let anchorName 449 // let anchorName
@@ -629,7 +629,7 @@ const getSuggestionsForOptions = (optionTyped, validOptions) => {
629 629
630 return suggestOptions.map( 630 return suggestOptions.map(
631 o => 631 o =>
632 new menuItem.Suggestion({ 632 menuItem.Suggestion({
633 text: `<span>${o.valueOf()}</span><span class='info' title="${o.desc ?? ''}">ⓘ</span>`, 633 text: `<span>${o.valueOf()}</span><span class='info' title="${o.desc ?? ''}">ⓘ</span>`,
634 replace: `${o.valueOf()}: `, 634 replace: `${o.valueOf()}: `,
635 cm, 635 cm,
@@ -649,7 +649,7 @@ const getSuggestionFromMapOption = option => {
649 ? `<span>${option.example_desc}</span><span class="truncate"style="color: gray">${option.example}</span>` 649 ? `<span>${option.example_desc}</span><span class="truncate"style="color: gray">${option.example}</span>`
650 : `<span>${option.example}</span>` 650 : `<span>${option.example}</span>`
651 651
652 return new menuItem.Suggestion({ 652 return menuItem.Suggestion({
653 text, 653 text,
654 replace: `${option.valueOf()}: ${option.example ?? ''}`, 654 replace: `${option.valueOf()}: ${option.example ?? ''}`,
655 cm, 655 cm,
@@ -665,7 +665,7 @@ const getSuggestionsFromAliases = option =>
665 Object.entries(aliasesForMapOptions[option.valueOf()] ?? {})?.map(record => { 665 Object.entries(aliasesForMapOptions[option.valueOf()] ?? {})?.map(record => {
666 const [alias, value] = record 666 const [alias, value] = record
667 const valueString = JSON.stringify(value).replaceAll('"', '') 667 const valueString = JSON.stringify(value).replaceAll('"', '')
668 return new menuItem.Suggestion({ 668 return menuItem.Suggestion({
669 text: `<span>${alias}</span><span class="truncate" style="color: gray">${valueString}</span>`, 669 text: `<span>${alias}</span><span class="truncate" style="color: gray">${valueString}</span>`,
670 replace: `${option.valueOf()}: ${valueString}`, 670 replace: `${option.valueOf()}: ${valueString}`,
671 cm, 671 cm,
@@ -789,7 +789,7 @@ const getSuggestions = anchor => {
789 }) 789 })
790 .map( 790 .map(
791 ([renderer, info]) => 791 ([renderer, info]) =>
792 new menuItem.Suggestion({ 792 menuItem.Suggestion({
793 text: `<span>use: ${renderer}</span><span class='info' title="${info.desc}">ⓘ</span>`, 793 text: `<span>use: ${renderer}</span><span class='info' title="${info.desc}">ⓘ</span>`,
794 replace: `use: ${renderer}`, 794 replace: `use: ${renderer}`,
795 cm, 795 cm,
@@ -799,7 +799,7 @@ const getSuggestions = anchor => {
799 ? [] 799 ? []
800 : [ 800 : [
801 ...rendererSuggestions, 801 ...rendererSuggestions,
802 new menuItem.Item({ 802 menuItem.Item({
803 innerHTML: '<a href="https://github.com/outdoorsafetylab/mapclay#renderer" class="external" style="display: block;">More...</a>', 803 innerHTML: '<a href="https://github.com/outdoorsafetylab/mapclay#renderer" class="external" style="display: block;">More...</a>',
804 className: ['suggestion'], 804 className: ['suggestion'],
805 onclick: () => window.open('https://github.com/outdoorsafetylab/mapclay#renderer', '_blank'), 805 onclick: () => window.open('https://github.com/outdoorsafetylab/mapclay#renderer', '_blank'),