MediaWiki:Common.js: Difference between revisions

From Artifacts of Capitalism
No edit summary
Tag: Reverted
No edit summary
 
(22 intermediate revisions by the same user not shown)
Line 1: Line 1:
// Replace the Chameleon search-box placeholder and button text
// ===============================
$(function() {
// LOAD CHART.JS (RELIABLE)
  // input field
// ===============================
  var inp = document.querySelector('#searchInput, input[name="search"]');
mw.loader.getScript("https://cdn.jsdelivr.net/npm/chart.js");
  if ( inp ) {
 
    inp.placeholder = 'Find an artifact…';    // your new placeholder
// ===============================
  }
// VIEWPORT FIX (iOS)
  // submit button (magnifying-glass)
// ===============================
   var btn = document.querySelector('#searchButton, button[type="submit"].mw-searchButton');
(function () {
  if ( btn ) {
   if (!document.querySelector('meta[name="viewport"]')) {
     btn.textContent = 'Go';                   // your new label, if you like
    var m = document.createElement('meta');
     m.name = 'viewport';
    m.content = 'width=device-width, initial-scale=1, shrink-to-fit=no';
    document.head.appendChild(m);
   }
   }
})();
// ===============================
// HIDE DRAFT NAMESPACE (NON-APPROVERS)
// ===============================
mw.hook('wikipage.content').add(function ($c) {
  var groups = mw.config.get('wgUserGroups') || [];
  if (groups.indexOf('approver') !== -1) return;
  $c.find('input[name="ns' + 3000 + '"]').closest('label, .mw-advancedSearch-ns_option').hide();
});
// ===============================
// GOOGLE CSE (ADVANCED SEARCH ONLY)
// ===============================
mw.loader.using('mediawiki.util').then(function () {
  var page = mw.config.get('wgPageName');
  if (page !== 'Artifacts_of_Capitalism:Advanced_search') return;
  window.__gcse = {
    searchCallbacks: {
      ready: function () {
        try {
          var params = new URLSearchParams(window.location.search);
          var q = params.get('q');
          if (q) {
            var hash = 'gsc.tab=0&gsc.q=' + encodeURIComponent(q);
            if (!window.location.hash.includes('gsc.q=')) {
              window.location.hash = hash;
            }
          }
        } catch (err) {
          console.warn('[CSE] Query error:', err);
        }
      }
    }
  };
  var script = document.createElement('script');
  script.async = true;
  script.src = 'https://cse.google.com/cse.js?cx=b194aa5e4d64344ad';
  document.body.appendChild(script);
});
// ===============================
// OPEN EXTERNAL LINKS IN NEW TAB
// ===============================
$(document).ready(function() {
  $('a.external').attr('target', '_blank');
});
});


// Tag login + create-account pages so CSS can target reliably
// ===============================
mw.loader.using([]).then(function () {
// CREATE ACCOUNT FIELD EXTENSIONS
   var sp = mw.config.get('wgCanonicalSpecialPageName');
// ===============================
   if (sp === 'Userlogin' || sp === 'CreateAccount') {
mw.loader.using('mediawiki.util').then(function () {
     document.documentElement.classList.add('aoc-auth');
   if (mw.config.get('wgCanonicalSpecialPageName') !== 'CreateAccount') return;
     document.body.classList.add('aoc-auth');
 
   }
   const observer = new MutationObserver(() => {
    const realNameInput = document.getElementById('wpRealName');
    if (!realNameInput) return;
 
    if (document.getElementById('wpAffiliation')) return;
 
    const affDiv = document.createElement('div');
    affDiv.className = 'mw-input';
    affDiv.innerHTML = `
      <label for="wpAffiliation">Affiliation</label>
      <input type="text" id="wpAffiliation" name="wpAffiliation" required class="mw-ui-input form-control"/>
    `;
 
    const instDiv = document.createElement('div');
     instDiv.className = 'mw-input';
    instDiv.innerHTML = `
      <label for="wpInstitutionalEmail">Institutional Email</label>
      <input type="email" id="wpInstitutionalEmail" name="wpInstitutionalEmail" required class="mw-ui-input form-control"/>
    `;
 
    const realNameDiv =
      realNameInput.closest('.mw-input, .form-group, p') || realNameInput.parentNode;
 
     realNameDiv.insertAdjacentElement('afterend', instDiv);
    realNameDiv.insertAdjacentElement('afterend', affDiv);
 
    observer.disconnect();
   });
 
  observer.observe(document.body, { childList: true, subtree: true });
});
});
mw.loader.using(['mediawiki.util'], function () {
  function qs(sel){ return document.querySelector(sel); }


  var toggler = qs('.p-navbar .navbar-toggler');
// ===============================
   var collapse = qs('.p-navbar .navbar-collapse');
// ARTIFACT MAP NETWORK LINES
  var search = qs('.p-navbar #p-search');
// ===============================
mw.hook('wikipage.content').add(function () {
 
  if (mw.config.get('wgPageName') !== 'Artifact_Map') return;
 
   function waitForMap(callback) {
    var attempts = 0;
    var maxAttempts = 30;
 
    var interval = setInterval(function () {
      attempts++;
 
      if (window.mw && mw.leafletMap && mw.leafletMap.map) {
        clearInterval(interval);
        callback(mw.leafletMap.map);
      }


  // Drawer toggle
      if (attempts > maxAttempts) {
  if (toggler && collapse) {
        clearInterval(interval);
    toggler.addEventListener('click', function (e) {
       }
      e.preventDefault();
 
       var isOpen = collapse.classList.toggle('show');
     }, 300);
      document.body.classList.toggle('offcanvas-open', isOpen);
     });
   }
   }


   // Click outside drawer to close
   waitForMap(function (map) {
  document.addEventListener('click', function (e) {
 
     if (!collapse || !collapse.classList.contains('show')) return;
    var el = document.getElementById("artifact-network-data");
     var inside = collapse.contains(e.target) || (toggler && toggler.contains(e.target));
     if (!el) return;
     if (!inside) {
 
       collapse.classList.remove('show');
     var raw = el.textContent.trim();
       document.body.classList.remove('offcanvas-open');
     if (!raw) return;
 
    var data;
    try {
       data = JSON.parse(raw);
    } catch (e) {
       console.error('[Artifact Map] JSON parse error:', e);
      return;
     }
     }
    var lookup = {};
    data.forEach(function(item) {
      if (item._pageName && item.Latitude && item.Longitude) {
        lookup[item._pageName] = [
          parseFloat(item.Latitude),
          parseFloat(item.Longitude)
        ];
      }
    });
    data.forEach(function(item) {
      if (!item.Related_artifacts || !item._pageName) return;
      var fromCoords = lookup[item._pageName];
      if (!fromCoords) return;
      item.Related_artifacts.split(",").forEach(function(rel) {
        var toCoords = lookup[rel.trim()];
        if (toCoords) {
          L.polyline([fromCoords, toCoords], {
            color: "purple",
            weight: 3,
            opacity: 0.8,
            dashArray: "4,6"
          }).addTo(map);
        }
      });
    });
   });
   });


  // Lightweight search overlay on mobile
});
  if (search) {
    var overlay = document.createElement('div');
    overlay.className = 'aoc-search-overlay';
    overlay.innerHTML = search.innerHTML; // reuse existing search form
    document.body.appendChild(overlay);


    search.addEventListener('click', function () {
// ===============================
      overlay.classList.add('show');
// COMMODITY CHART (FIXED + RELIABLE)
      var input = overlay.querySelector('input[type="search"], input[type="text"]');
// ===============================
       if (input) setTimeout(function(){ input.focus(); }, 10);
mw.hook('wikipage.content').add(function () {
 
  if (mw.config.get('wgPageName') !== 'Browse_Artifacts') return;
 
  setTimeout(function () {
 
    const el = document.getElementById('commodityChart');
    if (!el) return;
 
    const rawEl = document.getElementById('cargo-data');
    if (!rawEl) return;
 
    let raw = rawEl.textContent || "";
 
    raw = raw
      .replace(/^[^\[]*/, '')
      .replace(/[^\]]*$/, '')
      .trim();
 
    let data;
    try {
       data = JSON.parse(raw);
    } catch (e) {
      console.error("JSON parse failed:", e);
      return;
    }
 
    // 🔥 GROUP DATA IN JAVASCRIPT (instead of Cargo)
    const counts = {};
 
    data.forEach(item => {
      const key = item.Commodity || "Unknown";
      counts[key] = (counts[key] || 0) + 1;
     });
     });


     // close overlay on submit or outside click/escape
     const labels = Object.keys(counts);
    overlay.addEventListener('submit', function(){ overlay.classList.remove('show'); });
    const values = Object.values(counts);
     document.addEventListener('keydown', function(e){ if (e.key === 'Escape') overlay.classList.remove('show'); });
 
     document.addEventListener('click', function(e){
     if (typeof Chart === "undefined") {
       if (!overlay.classList.contains('show')) return;
      console.error("Chart.js not loaded");
       if (!overlay.contains(e.target) && !search.contains(e.target)) overlay.classList.remove('show');
      return;
    }
 
     new Chart(el, {
      type: 'bar',
      data: {
        labels: labels,
        datasets: [{
          data: values
        }]
       },
      options: {
        responsive: true,
        plugins: {
          legend: { display: false }
        },
        scales: {
          y: { beginAtZero: true }
        }
       }
     });
     });
  }, 500);
});
mw.loader.using('mediawiki.util').then(function () {
  var groups = mw.config.get('wgUserGroups') || [];
  if (
    groups.indexOf('sysop') !== -1 ||
    groups.indexOf('bureaucrat') !== -1 ||
    groups.indexOf('interface-admin') !== -1
  ) {
    document.body.classList.add('aoc-admin');
   }
   }
});
});

Latest revision as of 15:42, 27 March 2026

// ===============================
// LOAD CHART.JS (RELIABLE)
// ===============================
mw.loader.getScript("https://cdn.jsdelivr.net/npm/chart.js");

// ===============================
// VIEWPORT FIX (iOS)
// ===============================
(function () {
  if (!document.querySelector('meta[name="viewport"]')) {
    var m = document.createElement('meta');
    m.name = 'viewport';
    m.content = 'width=device-width, initial-scale=1, shrink-to-fit=no';
    document.head.appendChild(m);
  }
})();

// ===============================
// HIDE DRAFT NAMESPACE (NON-APPROVERS)
// ===============================
mw.hook('wikipage.content').add(function ($c) {
  var groups = mw.config.get('wgUserGroups') || [];
  if (groups.indexOf('approver') !== -1) return;
  $c.find('input[name="ns' + 3000 + '"]').closest('label, .mw-advancedSearch-ns_option').hide();
});

// ===============================
// GOOGLE CSE (ADVANCED SEARCH ONLY)
// ===============================
mw.loader.using('mediawiki.util').then(function () {
  var page = mw.config.get('wgPageName');
  if (page !== 'Artifacts_of_Capitalism:Advanced_search') return;

  window.__gcse = {
    searchCallbacks: {
      ready: function () {
        try {
          var params = new URLSearchParams(window.location.search);
          var q = params.get('q');
          if (q) {
            var hash = 'gsc.tab=0&gsc.q=' + encodeURIComponent(q);
            if (!window.location.hash.includes('gsc.q=')) {
              window.location.hash = hash;
            }
          }
        } catch (err) {
          console.warn('[CSE] Query error:', err);
        }
      }
    }
  };

  var script = document.createElement('script');
  script.async = true;
  script.src = 'https://cse.google.com/cse.js?cx=b194aa5e4d64344ad';
  document.body.appendChild(script);
});

// ===============================
// OPEN EXTERNAL LINKS IN NEW TAB
// ===============================
$(document).ready(function() {
  $('a.external').attr('target', '_blank');
});

// ===============================
// CREATE ACCOUNT FIELD EXTENSIONS
// ===============================
mw.loader.using('mediawiki.util').then(function () {
  if (mw.config.get('wgCanonicalSpecialPageName') !== 'CreateAccount') return;

  const observer = new MutationObserver(() => {
    const realNameInput = document.getElementById('wpRealName');
    if (!realNameInput) return;

    if (document.getElementById('wpAffiliation')) return;

    const affDiv = document.createElement('div');
    affDiv.className = 'mw-input';
    affDiv.innerHTML = `
      <label for="wpAffiliation">Affiliation</label>
      <input type="text" id="wpAffiliation" name="wpAffiliation" required class="mw-ui-input form-control"/>
    `;

    const instDiv = document.createElement('div');
    instDiv.className = 'mw-input';
    instDiv.innerHTML = `
      <label for="wpInstitutionalEmail">Institutional Email</label>
      <input type="email" id="wpInstitutionalEmail" name="wpInstitutionalEmail" required class="mw-ui-input form-control"/>
    `;

    const realNameDiv =
      realNameInput.closest('.mw-input, .form-group, p') || realNameInput.parentNode;

    realNameDiv.insertAdjacentElement('afterend', instDiv);
    realNameDiv.insertAdjacentElement('afterend', affDiv);

    observer.disconnect();
  });

  observer.observe(document.body, { childList: true, subtree: true });
});

// ===============================
// ARTIFACT MAP NETWORK LINES
// ===============================
mw.hook('wikipage.content').add(function () {

  if (mw.config.get('wgPageName') !== 'Artifact_Map') return;

  function waitForMap(callback) {
    var attempts = 0;
    var maxAttempts = 30;

    var interval = setInterval(function () {
      attempts++;

      if (window.mw && mw.leafletMap && mw.leafletMap.map) {
        clearInterval(interval);
        callback(mw.leafletMap.map);
      }

      if (attempts > maxAttempts) {
        clearInterval(interval);
      }

    }, 300);
  }

  waitForMap(function (map) {

    var el = document.getElementById("artifact-network-data");
    if (!el) return;

    var raw = el.textContent.trim();
    if (!raw) return;

    var data;
    try {
      data = JSON.parse(raw);
    } catch (e) {
      console.error('[Artifact Map] JSON parse error:', e);
      return;
    }

    var lookup = {};
    data.forEach(function(item) {
      if (item._pageName && item.Latitude && item.Longitude) {
        lookup[item._pageName] = [
          parseFloat(item.Latitude),
          parseFloat(item.Longitude)
        ];
      }
    });

    data.forEach(function(item) {

      if (!item.Related_artifacts || !item._pageName) return;

      var fromCoords = lookup[item._pageName];
      if (!fromCoords) return;

      item.Related_artifacts.split(",").forEach(function(rel) {
        var toCoords = lookup[rel.trim()];
        if (toCoords) {
          L.polyline([fromCoords, toCoords], {
            color: "purple",
            weight: 3,
            opacity: 0.8,
            dashArray: "4,6"
          }).addTo(map);
        }
      });

    });

  });

});

// ===============================
// COMMODITY CHART (FIXED + RELIABLE)
// ===============================
mw.hook('wikipage.content').add(function () {

  if (mw.config.get('wgPageName') !== 'Browse_Artifacts') return;

  setTimeout(function () {

    const el = document.getElementById('commodityChart');
    if (!el) return;

    const rawEl = document.getElementById('cargo-data');
    if (!rawEl) return;

    let raw = rawEl.textContent || "";

    raw = raw
      .replace(/^[^\[]*/, '')
      .replace(/[^\]]*$/, '')
      .trim();

    let data;
    try {
      data = JSON.parse(raw);
    } catch (e) {
      console.error("JSON parse failed:", e);
      return;
    }

    // 🔥 GROUP DATA IN JAVASCRIPT (instead of Cargo)
    const counts = {};

    data.forEach(item => {
      const key = item.Commodity || "Unknown";
      counts[key] = (counts[key] || 0) + 1;
    });

    const labels = Object.keys(counts);
    const values = Object.values(counts);

    if (typeof Chart === "undefined") {
      console.error("Chart.js not loaded");
      return;
    }

    new Chart(el, {
      type: 'bar',
      data: {
        labels: labels,
        datasets: [{
          data: values
        }]
      },
      options: {
        responsive: true,
        plugins: {
          legend: { display: false }
        },
        scales: {
          y: { beginAtZero: true }
        }
      }
    });

  }, 500);

});
mw.loader.using('mediawiki.util').then(function () {
  var groups = mw.config.get('wgUserGroups') || [];
  if (
    groups.indexOf('sysop') !== -1 ||
    groups.indexOf('bureaucrat') !== -1 ||
    groups.indexOf('interface-admin') !== -1
  ) {
    document.body.classList.add('aoc-admin');
  }
});