@panoramax/web-viewer
Version:
Panoramax web viewer for geolocated pictures
111 lines (100 loc) • 2.54 kB
JavaScript
import { icon } from "@fortawesome/fontawesome-svg-core";
import { setCustomIconLoader } from "iconify-icon";
import { TemakiIconURL } from "./services";
/**
* Transform Font Awesome icon definition into HTML element
* @param {IconDefinition} i The icon to use
* @param {object} [o] [FontAwesome icon parameters](https://origin.fontawesome.com/docs/apis/javascript/methods#icon-icondefinition-params)
* @returns {Element} HTML element
* @private
*/
export function fa(i, o) {
return icon(i, o).node[0];
}
/**
* Register more icons providers for Iconify
* @private
*/
export function moreIcons() {
setCustomIconLoader(async (name) => {
const response = await fetch(TemakiIconURL(name));
if (!response.ok) {
return null;
}
return {
body: await response.text()
};
}, "temaki");
}
/**
* Create a web component with its initial properties
* @private
*/
export function createWebComp(tag, props = {}) {
const wc = document.createElement(tag);
Object.entries(props).forEach(([k,v]) => {
if(k.startsWith("_")) { wc[k] = v; }
else if(k.startsWith("fn")) { wc[k.substring(2)] = v; }
else if(k.startsWith("on")) { wc.addEventListener(k.substring(2), v); }
else if(v) { wc.setAttribute(k, v); }
});
return wc;
}
/**
* Listen to parent events that may lead to a menu closure
* @private
*/
export function listenForMenuClosure(me, callback) {
// Other menu opened
me._parent?.addEventListener("menu-opened", e => {
if(e.detail.menu != me) { callback(); }
});
// Map click
me._parent?.onceMapReady?.().then(() => {
me._parent.map?.on?.("click", () => callback());
});
// Photo click
me._parent?.oncePSVReady?.().then(() => {
me._parent.psv.addEventListener("click", () => callback());
});
// Legend click
me._parent?.onceReady?.().then(() => {
me._parent.legend?.addEventListener("click", () => callback());
});
}
/** @private */
function lookForParent(comp) {
if(comp._parent) {
return comp._parent;
}
else if(comp === document.body) {
return null;
}
else if(comp.parentNode) {
return lookForParent(comp.parentNode);
}
else if(comp.host) {
return lookForParent(comp.host);
}
}
/**
* Wait for parent availability
* @private
*/
export function onceParentAvailable(comp) {
if(comp._parent) {
return Promise.resolve(comp._parent);
}
else {
return new Promise(resolve => {
const itv = setInterval(() => {
const p = lookForParent(comp);
if(p) {
comp._parent = p;
clearInterval(itv);
resolve(comp._parent);
}
}, 100);
});
}
}