UNPKG

@jinntec/jinn-codemirror

Version:

Source code editor component based on codemirror with language support for XML and Leiden+

157 lines (156 loc) 4.66 kB
import TomSelect from "tom-select"; function resolveURL(relPath) { const src = document.querySelector("script[src*=jinn-codemirror]"); if (src) { return new URL(relPath, src.src).href; } return new URL(relPath, window.location.href).href; } class ZoteroPicker extends HTMLElement { constructor() { super(); this._value = null; this.attachShadow({ mode: "open" }); } static get observedAttributes() { return ["value"]; } get value() { return this._value; } set value(value) { this._value = value; if (value && value.length > 0) { fetch(`https://api.zotero.org/groups/${this.group}/items?tag=${this._value}&format=bib&amp;style=digital-humanities-im-deutschsprachigen-raum`).then((response) => { if (response.ok) { return response.text(); } }).then((text) => { const item = { label: text, tag: this._value }; this._select.addOption(item); this._select.clear(true); this._select.sync(); this._select.setValue(value, false); this._select.sync(); this.setAttribute("value", value); }); } else { this.setAttribute("value", value); } } connectedCallback() { this.importTheme("default"); this.group = this.getAttribute("group"); const slot = document.createElement("slot"); this.shadowRoot?.appendChild(slot); let input = this.querySelector("input,select"); if (!input) { input = document.createElement("input"); input.setAttribute("autocomplete", "off"); this.appendChild(input); } const output = document.createElement("div"); output.className = "jinn-zotero-picker-output"; this.shadowRoot?.appendChild(output); let total = 0; const options = { load: (query, callback) => { if (query.length < 4) { return []; } fetch(`https://api.zotero.org/groups/${this.group}/items?q=${query}&sort=title&include=data,bib`).then((response) => { if (response.ok) { total = parseInt(response.headers.get("Total-Results") || "0"); return response.json(); } }).then((json) => { this._select?.clearOptions(); const data = []; if (total > 25) { data.push({ label: `${total} matching entries. Showing first 25.`, tag: "note", disabled: true }); } json.forEach((entry, n) => { if (entry.data.tags) { const item = { label: entry.bib }; if (entry.data.tags.length > 0) { item.tag = entry.data.tags[0].tag; } else { item.tag = `item-${n}`; item.disabled = true; } data.push(item); } }); callback(data); }).catch(() => { callback(); }); }, placeholder: "Zotero search", valueField: "tag", closeAfterSelect: true, searchField: [], create: false, maxItems: 1, loadThrottle: 500, render: { option: (data) => `<div>${data.label}</div>`, item: (data) => `<div>${data.tag}</div>` }, onChange: (value) => { const label = this._select.getOption(value, true); if (label) { output.innerHTML = label.innerHTML; } if (this._value === value) { return; } this._value = value; this.setAttribute("value", this._value); this._select.clearOptions(); this.dispatchEvent(new CustomEvent("change", { detail: this._value })); } }; this._select = new TomSelect(input, options); this.value = this.getAttribute("value"); } attributeChangedCallback(name, oldValue, newValue) { if (!oldValue || oldValue === newValue) { return; } if (name === "value") { this.value = newValue; } } importTheme(theme) { const context = this.getRootNode(); if (context.getElementById("__jinn-zotero-picker-css")) { return; } const themes = resolveURL("../css"); const link = document.createElement("link"); link.id = "__jinn-zotero-picker-css"; link.href = `${themes}/tom-select.${theme}.min.css`; link.rel = "stylesheet"; if (context.nodeType === Node.DOCUMENT_NODE) { document.head.appendChild(link); } else { context.appendChild(link); } } } window.customElements.define("jinn-zotero-picker", ZoteroPicker); export { ZoteroPicker };