MediaWiki:Common.js: Difference between revisions

No edit summary
No edit summary
 
(One intermediate revision by the same user not shown)
Line 1,728: Line 1,728:
                             if (g.authorIAST) el.setAttribute('data-cite-author-iast', g.authorIAST);
                             if (g.authorIAST) el.setAttribute('data-cite-author-iast', g.authorIAST);
                             var h = el.querySelector('.teeka-title');
                             var h = el.querySelector('.teeka-title');
                             if (h && g.name) h.textContent = g.name;
                            var label = teekaLabel(g);
                             if (h && label) h.textContent = label;
                            var slug = el.getAttribute('data-teeka-slug');
                            if (slug && label) {
                                labelBySlug[slug] = label;
                                // A footnote section for this commentary may
                                // already be on screen; rename it too.
                                document.querySelectorAll(
                                    '.gr-teeka-notes-group[data-teeka-slug="' + slug +
                                    '"] .gr-teeka-notes-title').forEach(function (t) {
                                        t.textContent = label;
                                    });
                            }
                         });
                         });
                     }($entry[0], entry.teekaGranthaId, entry.teekaPage));
                     }($entry[0], entry.teekaGranthaId, entry.teekaPage));
Line 3,007: Line 3,019:
             var h = document.createElement('div');
             var h = document.createElement('div');
             h.className = 'gr-teeka-notes-title';
             h.className = 'gr-teeka-notes-title';
             h.textContent = g.title || g.slug;
             h.textContent = (window.grLibrary && window.grLibrary.labelFor(g.slug))
                            || g.title || g.slug;
             wrap.appendChild(h);
             wrap.appendChild(h);
             var ol = document.createElement('ol');
             var ol = document.createElement('ol');
Line 3,161: Line 3,174:
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     var API = API_BASE.replace(/\/+$/, '');
     var API = API_BASE.replace(/\/+$/, '');
    var TTL = 6 * 60 * 60 * 1000;                // names change rarely
     var mem = {};
     var mem = {};
     var warned = false;
     var warned = false;
Line 3,169: Line 3,181:
     var libraryDown = !LIBRARY_ENABLED;
     var libraryDown = !LIBRARY_ENABLED;


     function cacheGet(id) {
     // In memory only, for the life of the page. Names used to be kept in
        if (mem[id]) return mem[id];
    // sessionStorage for six hours, which quietly outlived any correction
        try {
    // made in the library or on the map page. They now come from the map
            var raw = sessionStorage.getItem('gr-lib:' + id);
    // page, which is read once per load, so there is nothing to gain from
            if (!raw) return null;
    // a second cache that can disagree with it.
            var o = JSON.parse(raw);
    function cacheGet(id) { return mem[id] || null; }
            if (!o || (Date.now() - o.t) > TTL) return null;
     function cacheSet(id, v) { mem[id] = v; }
            mem[id] = o.v;
            return o.v;
        } catch (e) { return null; }
    }
     function cacheSet(id, v) {
        mem[id] = v;
        try { sessionStorage.setItem('gr-lib:' + id, JSON.stringify({ t: Date.now(), v: v })); }
        catch (e) { }
    }


     // The library returns camelCase fields; normalise to what the citation
     // The library returns camelCase fields; normalise to what the citation
Line 3,280: Line 3,283:
     function granthaMap() {
     function granthaMap() {
         if (mapPromise) return mapPromise;
         if (mapPromise) return mapPromise;
         var cached = null;
         // Deliberately NOT cached in sessionStorage. It was, for six hours,
         try {
        // which meant that editing the map page changed nothing for anyone
            var raw = sessionStorage.getItem('gr-lib:map');
        // whose tab had already read the old one - the exact failure you hit
            var o = raw && JSON.parse(raw);
        // while setting this up. mapPromise already collapses it to one
            if (o && (Date.now() - o.t) < TTL) cached = o.v;
        // request per page load, and the browser's own HTTP cache handles
        } catch (e) { }
        // the rest; a stale map is far more expensive than a small fetch.
        if (cached) { mapPromise = Promise.resolve(cached); return mapPromise; }
         try { sessionStorage.removeItem('gr-lib:map'); } catch (e) { }


         var url = (window.mw && mw.util && mw.util.getUrl)
         var url = (window.mw && mw.util && mw.util.getUrl)
Line 3,294: Line 3,297:
             .then(function (r) { return r.ok ? r.json() : {}; })
             .then(function (r) { return r.ok ? r.json() : {}; })
             .then(function (m) {
             .then(function (m) {
                 // Either a flat {page: id} object, or {pages:{...},
                 // Either a flat {page: id} object, or {pages, works,
                 // locators:{...}} when division names are recorded too.
                 // locators} when names and division names are recorded too.
                 m = m || {};
                 m = m || {};
                 if (!m.pages) m = { pages: m, locators: {} };
                 if (!m.pages) m = { pages: m };
                m.works = m.works || {};
                 m.locators = m.locators || {};
                 m.locators = m.locators || {};
                 try { sessionStorage.setItem('gr-lib:map', JSON.stringify({ t: Date.now(), v: m })); }
                 try {
                 catch (e) { }
                    if (!Object.keys(m.works).length) {
                        console.info('[grantha] the map page has no "works" section, ' +
                            'so names must come from the library API. Re-run ' +
                            'sync_grantha_map.py to embed them.');
                    }
                 } catch (e) { }
                 return m;
                 return m;
             })
             })
Line 3,340: Line 3,349:
             return lookup(gid).then(function (g) {
             return lookup(gid).then(function (g) {
                 if (!g) return;
                 if (!g) return;
                // On a commentary's own page the heading still reads as the
                // docx colophon ("...विरचिता प्रकाशिका"). Name it the way the
                // blocks are named instead.
                if (t.getAttribute('data-parent-doc')) {
                    var lab = teekaLabel(g);
                    if (lab) t.textContent = lab;
                } else if (g.name) {
                    t.textContent = g.name;
                }
                 if (g.name)      t.setAttribute('data-doc-title', g.name);
                 if (g.name)      t.setAttribute('data-doc-title', g.name);
                 if (g.nameIAST)  t.setAttribute('data-doc-title-iast', g.nameIAST);
                 if (g.nameIAST)  t.setAttribute('data-doc-title-iast', g.nameIAST);
Line 3,383: Line 3,401:
             return out;
             return out;
         });
         });
    }
    // How a commentary is named on screen: its author, then the work.
    // "श्रीवादिराजतीर्थः: काठकोपनिषद्भाष्यप्रकाशिका" - because several
    // commentaries on one moola share a work-type name (प्रकाशिका,
    // विवरणम्, खण्डार्थः), and the author is what actually tells them
    // apart for a reader scanning down the page.
    var labelBySlug = {};
    function teekaLabel(g) {
        if (!g) return '';
        var name = g.name || g.nameIAST || '';
        var author = g.author || g.authorIAST || '';
        if (!author || !name) return name || author;
        // Nothing to prefix if the work already opens with the author.
        if (name.indexOf(author) === 0) return name;
        return author + ': ' + name;
     }
     }


Line 3,424: Line 3,458:
     window.grLibraryVersion = '2026-09-30a';
     window.grLibraryVersion = '2026-09-30a';
     window.grLibrary = { lookup: lookup, lookupMany: lookupMany, catalogue: catalogue,
     window.grLibrary = { lookup: lookup, lookupMany: lookupMany, catalogue: catalogue,
                        teekaLabel: teekaLabel,
                        labelFor: function (slug) { return labelBySlug[slug] || ''; },
                         idForPage: idForPage, map: granthaMap, api: API,
                         idForPage: idForPage, map: granthaMap, api: API,
                         relabelDocLinks: relabelDocLinks };
                         relabelDocLinks: relabelDocLinks };