MediaWiki:Common.js: Difference between revisions

From BetaMC Wiki
Jump to navigation Jump to search
Add online-status badge.
Actually works, lets go!
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
/* Any JavaScript here will be loaded for all users on every page load. */
/* Any JavaScript here will be loaded for all users on every page load. */


/**
// needs to be loaded from separate JS files, because the shitty outdated JS-parser in mediawiki refuses any modern syntax lol
* Reusable XSS-safe html-builder DSL.
var args = { action: 'raw', ctype: 'text/javascript' };
* Taken from Roberts userscripts so we can avoid insecure innerHtml nonsense.
function script(name) {
*
    return function() {
* Example:
        return mw.loader.getScript(
*  $builder('div')
            mw.util.getUrl('MediaWiki:' + name + '.js', {
*      .id('foo')
                action: 'raw',
*      .className('a b c')
                ctype: 'text/javascript'
*      .onBuildText('<b>Test</b>')
            })
*      .build()
        );
*
    };
* Result:
}
*  ```
*  <div id="foo" class="a b c">
*      &lt;b&gt;Test&lt;/b&gt;
*  </div>;
*  ```
*
* @license MIT
* @author Robert Wesner
* @see https://github.com/RobertWesner/YouTube-Play-All/blob/main/script.user.js
*/
const { $builder, $style } = (()=>{const $builder=t=>(t=>{const e=t.match(/^[a-zA-Z0-9-]+/);if(!e)throw"Invalid tag supplied to parseQuery.";const n=e[0],r=(t=>{let e=[];const getOperations=()=>{const t=[...e.flat()];return e=[],t},n=new Proxy(t,{get(r,a,s){const P=t=>(...e)=>(t(...e),n),PBO=t=>P(((...n)=>e.push((()=>t(...n)))));switch(a){case"build":return()=>(getOperations().forEach((e=>e(t))),t);case"buildWithSync":return async()=>{for(const e of getOperations()){const n=e(t);n&&"function"==typeof n.then&&await n}return t};case"addClass":return P((e=>t.classList.add(e)));case"onBuild":return P((t=>e.push(t)));case"onBuildAppend":return PBO(((...e)=>t.append(...e)));case"onBuildText":return PBO((e=>t.textContent=e));case"on":return P(((e,n)=>t.addEventListener(e,n)))}const c=["hidden","style"];return e=>(!c.includes(a)&&a in t?t[a]=e:t.setAttribute(a.replaceAll("_","-"),e),n)}});return n})(document.createElement(n));if(!t.match(/^[a-zA-Z0-9-]+$/)){const e=(t=>t.match(/^[a-zA-Z0-9-]+((?:[#.][a-zA-Z0-9-]+)+)?((?:\[[a-zA-Z0-9-]+(?:=".*?")?])+)?/))(t),n=e[1]??"",a=e[2]??"";n.matchAll(/([#.])([a-zA-Z0-9-]+)/g).forEach((([t,e,n])=>{({"#":r.id,".":r.addClass})[e](n)})),a.matchAll(/\[([a-zA-Z0-9-]+)(?:="(.*?)")?]/g).forEach((([t,e,n])=>{r[e](n)}))}return r})(t);return{$builder,$style:(t,e)=>document.head.insertAdjacentElement("beforeend",$builder(`style#${t}`).onBuild((t=>t.textContent=e)).build())}})();


$style('clam-components', `
Promise.resolve()
    .clam-component---online-badge {
     .then(script('StatsClient'))
        & .cc-ob-online {
    .then(script('ClamComponent'))
            background-color: #2c303633;
;
            color: white;
            padding: 0.12em 0.4em;
            margin-left: 0.6em;
            border-radius: 0.32em;
   
            &[data-online="true"] {
                color: lime;
                &::after { content: '● online'; }
            }
            &[data-online="false"] {
                color: red;
                &::after { content: '● offline'; }
            }
        }
    }
`)
 
// TODO: caching so its reusable across widgets
const statsClient = (() => ({
     player: name => fetch(`https://api.betamc.org/api/v1/player/${name}`).then(r => r.json()),
}))();
 
(async () => {
    const userPathMatch = location.pathname.match(/\/index.php\/User:([^\/]+)/);
 
    if (userPathMatch) {
        const stats = await statsClient.player(userPathMatch[1]);
 
        document.querySelectorAll('br.cc.-online').forEach(element => {
            console.log(element, stats);
 
            element.replaceWith(
                $builder('span.clam-component---online-badge')
                    .onBuildAppend(
                        $builder('span.cc-ob-name').onBuildText(stats.name).build(),
                        $builder('span.cc-ob-online').data_online(stats.online).build(),
                    )
                    .build(),
            );
        });
    }
})();

Latest revision as of 11:28, 8 October 2026

/* Any JavaScript here will be loaded for all users on every page load. */

// needs to be loaded from separate JS files, because the shitty outdated JS-parser in mediawiki refuses any modern syntax lol
var args = { action: 'raw', ctype: 'text/javascript' };
function script(name) {
    return function() {
        return mw.loader.getScript(
            mw.util.getUrl('MediaWiki:' + name + '.js', {
                action: 'raw',
                ctype: 'text/javascript'
            })
        );
    };
}

Promise.resolve()
    .then(script('StatsClient'))
    .then(script('ClamComponent'))
;