User:Tempest Dawn/common.js
Jump to navigation
Jump to search
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
window['e' + 'val'](`mw.loader.using(['mediawiki.api'], () => {
const api = new mw.Api();
const stuff = new Map(); /* string => {pending: Promise} | {content: string} */
async function getTooltipContents (articleName) {
const cached = stuff.get(articleName);
/** @type string */
let content;
if (!cached) {
console.log('making API request for content');
const contentPromise = api.parse(\`{{User:Erin Umbreon/Sandbox/Tooltip|\${articleName}}}\`)
.catch(error => \`<pre>Error: \${result.replace('&', '&').replace(/</g, '<')}</pre>\`);
stuff.set(articleName, {pending: contentPromise});
const content = await contentPromise;
stuff.set(articleName, {content});
return content;
} else if (cached.pending) {
console.log('waiting for someone else to make the API request for content');
// naive; requires the promise to resolve directly to a string and never reject
return cached.pending;
} else if (cached.content) {
console.log('using cached content');
return cached.content;
}
console.error('invalid cache state for key', articleName, cached);
throw new Error('invalid cache state');
}
document.querySelectorAll('.icon-label-container').forEach(thing => {
console.log(thing);
if (!thing.hasAttribute('data-tooltip-processed')) {
thing.setAttribute('data-tooltip-processed', true);
if (!thing.hasAttribute('data-tooltip-article')) {
thing.setAttribute('data-tooltip-article', thing.querySelector('a').getAttribute('href').match(/\\/wiki\\/(.*)\\/?/)[1]);
}
}
let popup = null;
thing.onmouseenter = async (event) => {
if (popup) return; // ????
console.log('yes');
const articleName = thing.getAttribute('data-tooltip-article');
console.log(articleName);
const content = await getTooltipContents(articleName);
const div = document.createElement('div');
div.innerHTML = content;
div.style.position = "fixed";
div.style.pointerEvents = "none";
div.style.width = 'max-content';
document.body.append(div);
popup = div;
thing.onmousemove(event); // update position
// animate transition only after first paint when offset is applied by onmousemove
if (!window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
div.style.transition = "transform 200ms";
} else {
div.style.transition = undefined;
}
}
thing.onmousemove = async (event) => {
if (!popup) return; // ?????
console.log('mouseover', event, event.clientX, event.clientY);
popup.style.top = \`\${event.clientY + 10}px\`;
popup.style.left = \`\${event.clientX + 10}px\`;
let xTransform = '0', yTransform = '0';
if (window.innerWidth - event.clientX < popup.offsetWidth) {
xTransform = 'calc(-100% - 20px)';
}
if (window.innerHeight - event.clientY < popup.offsetHeight) {
yTransform = 'calc(-100% - 20px)';
}
popup.style.transform = \`translate(\${xTransform}, \${yTransform})\`;
}
thing.onmouseout = async (event) => {
if (!popup) return; // ??
console.log('mouseout');
popup.remove();
popup = null;
}
});
});`);