1class PreviewPlugin { 2 3 #preview = null; 4 #abortController = null; 5 6 constructor() { 7 this.#preview = document.createElement('div'); 8 this.#preview.classList.add('plugin-preview'); 9 this.#preview.style.position = 'absolute'; 10 this.#preview.style.top = '0'; 11 this.#preview.style.left = '0'; 12 this.#preview.style.display = 'none'; 13 document.body.append(this.#preview); 14 } 15 16 attach() { 17 const selector = JSINFO.plugin.preview.selector; 18 const links = document.querySelectorAll(selector + ' a.wikilink1'); 19 links.forEach(link => { 20 link.addEventListener('mouseenter', this.onMouseEnter.bind(this)); 21 link.addEventListener('mouseleave', this.onMouseLeave.bind(this)); 22 link.removeAttribute('title'); 23 }); 24 } 25 26 async loadPreview(id) { 27 try { 28 if (this.#abortController !== null) this.#abortController.abort(); 29 this.#abortController = new AbortController(); 30 31 const data = await fetch( 32 DOKU_BASE + 'lib/exe/ajax.php?call=plugin_preview&id=' + encodeURIComponent(id), 33 { 34 signal: this.#abortController.signal, 35 method: 'POST', 36 } 37 ); 38 if (data.ok) { 39 this.#preview.innerHTML = await data.text(); 40 this.#preview.style.display = 'block'; 41 } 42 } catch (ignored) { 43 // we don't care about errors 44 } 45 } 46 47 async onMouseEnter(e) { 48 this.#preview.style.top = e.pageY + 10 + 'px'; 49 this.#preview.style.left = e.pageX + 10 + 'px'; 50 await this.loadPreview(e.target.dataset.wikiId); 51 } 52 53 onMouseLeave(e) { 54 this.#preview.style.display = 'none'; 55 if (this.#abortController !== null) this.#abortController.abort(); 56 this.#abortController = null; 57 } 58 59} 60 61 62document.addEventListener('DOMContentLoaded', () => { 63 const preview = new PreviewPlugin(); 64 preview.attach(); 65}); 66