From c51da12b17e26f7802bc9ba39f7e7089cbeb0cbe Mon Sep 17 00:00:00 2001 From: Hsieh Chin Fan Date: Tue, 24 Sep 2024 23:16:07 +0800 Subject: refactor: methods about creating geo/doc links change methods to only create a single link --- src/dumbymap.mjs | 110 ++++++++++++++++++++++++++++--------------------------- src/editor.mjs | 21 +++++------ 2 files changed, 66 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs index 7408529..a563c88 100644 --- a/src/dumbymap.mjs +++ b/src/dumbymap.mjs @@ -21,70 +21,69 @@ const mapCache = {} // FUNCTION: Get DocLinks from special anchor element {{{ /** - * CreateDocLinks. + * CreateDocLink. * * @param {HTMLElement} Elements contains anchor elements for doclinks - * @returns {Array} List of doclinks just created */ -export const createDocLinks = (container) => Array.from(container.querySelectorAll(docLinkSelector)) - .map(link => { - link.classList.add('with-leader-line', 'doclink') - link.lines = [] +export const createDocLink = (link) => { + link.classList.add('with-leader-line', 'doclink') + link.lines = [] - link.onmouseover = () => { - const label = decodeURIComponent(link.href.split('#')[1]) - const selector = link.title.split('=>')[1] ?? '#' + label - const target = document.querySelector(selector) - if (!target?.checkVisibility()) return - - const line = new LeaderLine({ - start: link, - end: target, - middleLabel: LeaderLine.pathLabel({ - text: label, - fontWeight: 'bold', - }), - hide: true, - path: "magnet" - }) - link.lines.push(line) - line.show('draw', { duration: 300, }) - } - link.onmouseout = () => { - link.lines.forEach(line => line.remove()) - link.lines.length = 0 - } + link.onmouseover = () => { + const label = decodeURIComponent(link.href.split('#')[1]) + const selector = link.title.split('=>')[1] ?? '#' + label + const target = document.querySelector(selector) + if (!target?.checkVisibility()) return - return link - }) + const line = new LeaderLine({ + start: link, + end: target, + middleLabel: LeaderLine.pathLabel({ + text: label, + fontWeight: 'bold', + }), + hide: true, + path: "magnet" + }) + link.lines.push(line) + line.show('draw', { duration: 300, }) + } + link.onmouseout = () => { + link.lines.forEach(line => line.remove()) + link.lines.length = 0 + } +} // }}} // FUNCTION: Get GeoLinks from special anchor element {{{ /** * Create geolinks, which points to map by geo schema and id * * @param {HTMLElement} Elements contains anchor elements for doclinks - * @returns {Array} List of doclinks just created + * @returns {Boolean} ture is link is created, false if coordinates are invalid */ -export const createGeoLinks = (container, callback) => Array.from(container.querySelectorAll(geoLinkSelector)) - .filter(link => { - const url = new URL(link.href) - const xy = url?.href?.match(/^geo:([0-9.,]+)/)?.at(1)?.split(',')?.reverse()?.map(Number) - - if (!xy || isNaN(xy[0]) || isNaN(xy[1])) return false - - // Geo information in link - link.url = url - link.xy = xy - link.classList.add('with-leader-line', 'geolink') - link.targets = link.url.searchParams.get('id')?.split(',') ?? null - - // LeaderLine - link.lines = [] - callback(link) - - return true - }) +export const createGeoLink = (link, callback = null) => { + const url = new URL(link.href) + const xyInParams = url.searchParams.get('xy') + const xy = xyInParams + ? xyInParams.split(',')?.map(Number) + : url?.href?.match(/^geo:([0-9.,]+)/)?.at(1)?.split(',')?.reverse()?.map(Number) + + if (!xy || isNaN(xy[0]) || isNaN(xy[1])) return false + + // Geo information in link + link.url = url + link.xy = xy + link.classList.add('with-leader-line', 'geolink') + link.targets = link.url.searchParams.get('id')?.split(',') ?? null + + // LeaderLine + link.lines = [] + callback?.call(this, link) + + return true +} // }}} + export const markdown2HTML = (container, mdContent) => { // Render: Markdown -> HTML {{{ Array.from(container.children).map(e => e.remove()) @@ -171,9 +170,12 @@ export const generateMaps = (container, callback) => { // LeaderLine {{{ + Array.from(container.querySelectorAll(docLinkSelector)) + .filter(createDocLink) + // Get anchors with "geo:" scheme htmlHolder.anchors = [] - const geoLinks = createGeoLinks(htmlHolder, (link) => { + const geoLinkCallback = (link) => { link.onmouseover = () => addLeaderLines(link) link.onmouseout = () => removeLeaderLines(link) link.onclick = (event) => { @@ -184,7 +186,9 @@ export const generateMaps = (container, callback) => { // TODO Just hide leader line and show it again removeLeaderLines(link) } - }) + } + const geoLinks = Array.from(container.querySelectorAll(geoLinkSelector)) + .filter(l => createGeoLink(l, geoLinkCallback)) const isAnchorPointedBy = (link) => (anchor) => { const mapContainer = anchor.closest('.map-container') diff --git a/src/editor.mjs b/src/editor.mjs index 539a770..ab5db42 100644 --- a/src/editor.mjs +++ b/src/editor.mjs @@ -1,6 +1,6 @@ /*global EasyMDE*/ /*eslint no-undef: "error"*/ -import { markdown2HTML, generateMaps, createDocLinks } from './dumbymap' +import { markdown2HTML, generateMaps } from './dumbymap' import { defaultAliases, parseConfigsFromYaml } from 'mapclay' import { Suggestion } from './MenuItem' @@ -88,11 +88,17 @@ if (contentFromHash) { editor.cleanup() editor.value(contentFromHash) } - // }}} // Set up logic about editor content {{{ +const afterMapRendered = (_) => { + // mapHolder.oncontextmenu = (event) => { + // event.preventDefault() + // const lonLat = mapHolder.renderer.unproject([event.x, event.y]) + // // TODO... + // } +} markdown2HTML(HtmlContainer, editor.value()) -createDocLinks(HtmlContainer) +dumbymap = generateMaps(HtmlContainer, afterMapRendered) // Quick hack to style lines inside code block const addClassToCodeLines = () => { @@ -159,17 +165,8 @@ const debounceForMap = (() => { } })() -const afterMapRendered = (_) => { - // mapHolder.oncontextmenu = (event) => { - // event.preventDefault() - // const lonLat = mapHolder.renderer.unproject([event.x, event.y]) - // // TODO... - // } -} - const updateDumbyMap = () => { markdown2HTML(HtmlContainer, editor.value()) - createDocLinks(HtmlContainer) // TODO Test if generate maps intantly is OK with map cache // debounceForMap(HtmlContainer, afterMapRendered) dumbymap = generateMaps(HtmlContainer, afterMapRendered) -- cgit v1.2.3-70-g09d2