Loading src/components/LIcon.vue +84 −15 Original line number Diff line number Diff line <script> import { onMounted, reactive, ref, inject } from "vue"; import { props, setup as iconSetup } from "../functions/icon"; import { generatePlaceholderMethods } from "../utils"; import { onMounted, ref, inject, nextTick, h } from "vue"; import { propsBinder, remapEvents } from "../utils"; import { props } from "../functions/icon"; /** * Icon component, lets you add and custom icons to the map Loading @@ -10,27 +10,96 @@ export default { name: "LIcon", props, setup(props, context) { const leafletRef = ref({}); const schematics = generatePlaceholderMethods([ "DomEvent", "divIcon", "icon", ]); const root = ref(null); const setIcon = inject("setIcon"); const canSetParentHtml = inject("canSetParentHtml"); const setParentHtml = inject("setParentHtml"); const setIcon = inject("setIcon"); let onDomEvent; let offDomEvent; let divIcon; let icon; let iconObject = undefined; const createIcon = (el, recreationNeeded, htmlSwapNeeded) => { const elHtml = el && el.innerHTML; if (!recreationNeeded) { if (htmlSwapNeeded && iconObject && canSetParentHtml()) { setParentHtml(elHtml); } return; } const listeners = remapEvents(context.attrs); if (iconObject) { offDomEvent(iconObject, listeners); } const options = { ...props, }; if (elHtml) { options.html = elHtml; } iconObject = options.html ? divIcon(options) : icon(options); onDomEvent(iconObject, listeners); setIcon(iconObject); }; const scheduleCreateIcon = () => { nextTick(() => createIcon(root.value, true, false)); }; const scheduleHtmlSwap = () => { nextTick(() => createIcon(root.value, false, true)); }; const methods = { setIconUrl: scheduleCreateIcon, setIconRetinaUrl: scheduleCreateIcon, setIconSize: scheduleCreateIcon, setIconAnchor: scheduleCreateIcon, setPopupAnchor: scheduleCreateIcon, setTooltipAnchor: scheduleCreateIcon, setShadowUrl: scheduleCreateIcon, setShadowRetinaUrl: scheduleCreateIcon, setShadowAnchor: scheduleCreateIcon, setBgPos: scheduleCreateIcon, setClassName: scheduleCreateIcon, setHtml: scheduleCreateIcon, }; onMounted(async () => { const { DomEvent, divIcon, icon } = await import( const { DomEvent, divIcon: lDivIcon, icon: lIcon } = await import( "leaflet/dist/leaflet-src.esm" ); schematics.DomEvent = DomEvent; schematics.divIcon = divIcon; schematics.icon = icon; leafletRef.value = onDomEvent = DomEvent.on; offDomEvent = DomEvent.off; divIcon = lDivIcon; icon = lIcon; propsBinder(methods, {}, props); const observer = new MutationObserver(scheduleHtmlSwap); observer.observe(root.value, { attributes: true, childList: true, characterData: true, subtree: true, }); scheduleCreateIcon(); }); return { root }; }, render() { const content = this.$slots.default ? this.$slots.default() : undefined; return h("div", { ref: "root" }, content); }, }; </script> src/functions/icon.js +0 −31 Original line number Diff line number Diff line import { ref, nextTick } from "vue"; export const props = { iconUrl: { type: String, Loading Loading @@ -67,32 +65,3 @@ export const props = { default: () => ({}), }, }; export const setup = (props, mapRef, context, leafletMethods) => { let recreationNeeded = false; let htmlSwapNeeded = false; let iconObject = undefined; const options = { ...props, }; const createIcon = () => { if (htmlSwapNeeded && !recreationNeeded && iconObject) }; const methods = { scheduleCreateIcon() { recreationNeeded.value = true; nextTick(createIcon); }, scheduleHtmlSwap() { htmlSwapNeeded.value = true; nextTick(createIcon); }, createIcon, }; return { options, methods }; }; Loading
src/components/LIcon.vue +84 −15 Original line number Diff line number Diff line <script> import { onMounted, reactive, ref, inject } from "vue"; import { props, setup as iconSetup } from "../functions/icon"; import { generatePlaceholderMethods } from "../utils"; import { onMounted, ref, inject, nextTick, h } from "vue"; import { propsBinder, remapEvents } from "../utils"; import { props } from "../functions/icon"; /** * Icon component, lets you add and custom icons to the map Loading @@ -10,27 +10,96 @@ export default { name: "LIcon", props, setup(props, context) { const leafletRef = ref({}); const schematics = generatePlaceholderMethods([ "DomEvent", "divIcon", "icon", ]); const root = ref(null); const setIcon = inject("setIcon"); const canSetParentHtml = inject("canSetParentHtml"); const setParentHtml = inject("setParentHtml"); const setIcon = inject("setIcon"); let onDomEvent; let offDomEvent; let divIcon; let icon; let iconObject = undefined; const createIcon = (el, recreationNeeded, htmlSwapNeeded) => { const elHtml = el && el.innerHTML; if (!recreationNeeded) { if (htmlSwapNeeded && iconObject && canSetParentHtml()) { setParentHtml(elHtml); } return; } const listeners = remapEvents(context.attrs); if (iconObject) { offDomEvent(iconObject, listeners); } const options = { ...props, }; if (elHtml) { options.html = elHtml; } iconObject = options.html ? divIcon(options) : icon(options); onDomEvent(iconObject, listeners); setIcon(iconObject); }; const scheduleCreateIcon = () => { nextTick(() => createIcon(root.value, true, false)); }; const scheduleHtmlSwap = () => { nextTick(() => createIcon(root.value, false, true)); }; const methods = { setIconUrl: scheduleCreateIcon, setIconRetinaUrl: scheduleCreateIcon, setIconSize: scheduleCreateIcon, setIconAnchor: scheduleCreateIcon, setPopupAnchor: scheduleCreateIcon, setTooltipAnchor: scheduleCreateIcon, setShadowUrl: scheduleCreateIcon, setShadowRetinaUrl: scheduleCreateIcon, setShadowAnchor: scheduleCreateIcon, setBgPos: scheduleCreateIcon, setClassName: scheduleCreateIcon, setHtml: scheduleCreateIcon, }; onMounted(async () => { const { DomEvent, divIcon, icon } = await import( const { DomEvent, divIcon: lDivIcon, icon: lIcon } = await import( "leaflet/dist/leaflet-src.esm" ); schematics.DomEvent = DomEvent; schematics.divIcon = divIcon; schematics.icon = icon; leafletRef.value = onDomEvent = DomEvent.on; offDomEvent = DomEvent.off; divIcon = lDivIcon; icon = lIcon; propsBinder(methods, {}, props); const observer = new MutationObserver(scheduleHtmlSwap); observer.observe(root.value, { attributes: true, childList: true, characterData: true, subtree: true, }); scheduleCreateIcon(); }); return { root }; }, render() { const content = this.$slots.default ? this.$slots.default() : undefined; return h("div", { ref: "root" }, content); }, }; </script>
src/functions/icon.js +0 −31 Original line number Diff line number Diff line import { ref, nextTick } from "vue"; export const props = { iconUrl: { type: String, Loading Loading @@ -67,32 +65,3 @@ export const props = { default: () => ({}), }, }; export const setup = (props, mapRef, context, leafletMethods) => { let recreationNeeded = false; let htmlSwapNeeded = false; let iconObject = undefined; const options = { ...props, }; const createIcon = () => { if (htmlSwapNeeded && !recreationNeeded && iconObject) }; const methods = { scheduleCreateIcon() { recreationNeeded.value = true; nextTick(createIcon); }, scheduleHtmlSwap() { htmlSwapNeeded.value = true; nextTick(createIcon); }, createIcon, }; return { options, methods }; };