32 خطوط
2.6 KiB
JavaScript
32 خطوط
2.6 KiB
JavaScript
/** Construct inert embed markup, retaining the read capability only in the URL fragment. */
|
|
export function viewerURL(value, token, base = location.origin) {
|
|
const url = new URL(value, base);
|
|
if (!['https:', 'http:'].includes(url.protocol)) throw new Error('Invalid viewer URL');
|
|
if (url.username || url.password) throw new Error('Invalid viewer URL');
|
|
if (token) url.hash = new URLSearchParams({ token }).toString();
|
|
return url.href;
|
|
}
|
|
export function iframeCode(value, base = location.origin) {
|
|
const url = viewerURL(value, null, base);
|
|
const escaped = url.replace(/[&"<>']/g, c => ({'&':'&','"':'"','<':'<','>':'>',"'":'''}[c]));
|
|
return `<iframe\n src="${escaped}"\n width="100%"\n height="800"\n title="Altium design viewer"\n loading="lazy"\n referrerpolicy="no-referrer"\n allowfullscreen\n></iframe>`;
|
|
}
|
|
export function mountShare(host, value) {
|
|
const code = iframeCode(value), widget = document.createElement('div');widget.className = 'share-widget';
|
|
const toggle = document.createElement('button');toggle.type = 'button';toggle.className = 'share-toggle';toggle.textContent = 'Share';toggle.setAttribute('aria-expanded','false');
|
|
const panel = document.createElement('div');panel.className = 'share-panel';panel.hidden = true;
|
|
const caption = document.createElement('p');caption.textContent = 'Embed this viewer in Gitea or this service:';
|
|
const text = document.createElement('textarea');text.readOnly = true;text.value = code;text.rows = 9;text.setAttribute('aria-label','Viewer iframe code');
|
|
const note = document.createElement('p');note.className = 'share-note';
|
|
note.textContent = new URL(value,location.origin).hash.includes('token=') ? 'This code includes a read token. Anyone with the code can view this design.' : 'Embedding is allowed only on this service and https://git.sadentel.net.';
|
|
const copy = document.createElement('button');copy.type = 'button';copy.textContent = 'Copy iframe';
|
|
const status = document.createElement('span');status.setAttribute('role','status');
|
|
copy.addEventListener('click',async()=>{
|
|
try { await navigator.clipboard.writeText(code);status.textContent = 'Copied'; }
|
|
catch { text.focus();text.select();status.textContent = 'Select and copy the code manually.'; }
|
|
});
|
|
toggle.addEventListener('click',()=>{panel.hidden=!panel.hidden;toggle.setAttribute('aria-expanded',String(!panel.hidden));});
|
|
widget.addEventListener('keydown',event=>{if(event.key==='Escape'){panel.hidden=true;toggle.setAttribute('aria-expanded','false');toggle.focus();}});
|
|
panel.append(caption,text,note,copy,status);widget.append(toggle,panel);host.append(widget);
|
|
}
|