MediaWiki:Common.js: Difference between revisions

From semantic-hub.io
No edit summary
Undo revision 574 by Admin (talk)
 
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
/* Any JavaScript here will be loaded for all users on every page load. */
mw.loader.load('/w/index.php?title=MediaWiki:CustomExtensions&action=raw&ctype=text/javascript');


/**
// Note: I had to comment out the following parts since it crashed the global JS
* EntitySchema Enhancement Scripts
//      23.04.26, 23:30 P.Wagner (FoP Consult)
* Loaded for all users automatically
*/


// Load EntitySchemaHighlighter
// mw.loader.using(['mediawiki.util']).then(function () {
// ----------------------------
//     if (mw.config.get('wgPageName') !== 'Item:Q5' || mw.config.get('wgAction') !== 'view') {
// Source: https://www.wikidata.org/wiki/User:Zvpunry/EntitySchemaHighlighter.js
//         return;
 
//    }
$(function() {
//
  const entityRegEx = /\b[PQ]\d+(?=\b|_)/g;
//     const apiUrl = 'http://127.0.0.1:5000/api/v3/search?search=Volt&lang=en&types=unit';
  const scriptName = 'SchemaItemPropertyHighlighter';
//
 
//     function normalizeText(text) {
  function markupEntities(html, entitiesData) {
//        return (text || '')
     return html.replace(entityRegEx, function(match) {
//            .replace(/\s+/g, ' ')
      if (
//            .trim()
        !entitiesData[match] ||
//             .toLowerCase();
        typeof entitiesData[match].missing !== 'undefined'
//     }
      ) {
//
        return match;
//    function extractValues(data) {
      }
//         const result = data?.result || {};
      return $('<a>')
//        const embedded = (result.embeddedDataSpecifications || [])[0] || {};
        .attr({
//        const content = embedded.dataSpecificationContent || {};
          href: 'https://semantic-hub.io/wiki/' + entitiesData[match].title,
//
          title: entitiesData[match].labels.en.value,
//        const preferredNameRaw = content.preferredName?.value;
        })
//        const symbolRaw = content.Symbol?.value;
         .text(match)[0].outerHTML;
//
    });
//        let preferredName = '—';
  }
//        if (Array.isArray(preferredNameRaw)) {
 
//             preferredName = preferredNameRaw
  async function requestEntitiesData(listOfEntities) {
//                 .map(v => typeof v === 'object' && v !== null ? (v.value || JSON.stringify(v)) : String(v))
    const entityBatches = splitIntoBatches(listOfEntities);
//                .join(', ');
 
//        } else if (preferredNameRaw) {
    const data = {};
//            preferredName = typeof preferredNameRaw === 'object'
    for (const batch of entityBatches) {
//                ? (preferredNameRaw.value || JSON.stringify(preferredNameRaw))
      let dataBatch = await requestBatchEntitiesData(batch);
//                : String(preferredNameRaw);
      Object.assign(data, dataBatch);
//        }
    }
//
 
//        let symbol = '';
    return data;
//        if (symbolRaw) {
  }
//            symbol = typeof symbolRaw === 'object'
 
//                ? (symbolRaw.value || JSON.stringify(symbolRaw))
  async function requestBatchEntitiesData(listOfEntities) {
//                : String(symbolRaw);
    const urlBase = 'https://semantic-hub.io/w/api.php';
//        }
    const urlParams = {
//
      action: 'wbgetentities',
//         return {
      ids: listOfEntities.join('|'),
//            'id': result.id || '—',
      props: 'labels|info',
//             'idshort': result.idShort || '—',
      languages: 'en',
//             'preferred name': preferredName,
      format: 'json',
//            'preferredname': preferredName,
      origin: '*',
//            'symbol': symbol
    };
//         };
 
//    }
    return fetch(urlBase + '?' + jQuery.param(urlParams))
//
      .then(function(response) {
//    function setCellValue(row, value) {
        return response.json();
//        if (!row) return false;
      })
//
      .then(function(responseData) {
//         let valueCell =
         if (responseData.error) {
//            row.querySelector('td') ||
          console.warn('Error in userscript: ' + scriptName);
//            row.querySelector('.wikibase-statementview-mainsnak-container') ||
          console.warn({
//            row.querySelector('.wikibase-snakview-value') ||
            code: responseData.error.code,
//            row.querySelector('.wikibase-statementview-mainsnak');
             info: responseData.error.info,
//
             servedby: responseData.servedby,
//        if (!valueCell) return false;
          });
//
          return;
//        const target =
         }
//            valueCell.querySelector('.wikibase-snakview-value') ||
        return responseData.entities;
//            valueCell;
      });
//
  }
//        target.textContent = value;
 
//        return true;
  function splitIntoBatches(listOfEntities) {
//    }
    const maxBatchSize = 50.0;
//
    return listOfEntities.reduce((acc, cur, i) => {
//    function fillExistingTable(values) {
      const index = Math.floor(i / maxBatchSize);
//        const rows = document.querySelectorAll('tr, .wikibase-statementview');
      if (!acc[index]) {
//
         acc[index] = [];
//        let filled = 0;
      }
//
      acc[index].push(cur);
//        rows.forEach(function (row) {
      return acc;
//            const headerText = normalizeText(row.textContent);
    }, []);
//
  }
//            if (!headerText) return;
 
//
  function getListOfEntitiesFromSchemaText(schemaText) {
//            if (headerText.includes('idshort')) {
    return [...new Set(schemaText.match(entityRegEx))];
//                if (setCellValue(row, values['idshort'])) filled++;
  }
//             } else if (headerText.includes('preferred name') || headerText.includes('preferredname')) {
 
//                 if (setCellValue(row, values['preferredname'])) filled++;
  const $schemaText = $('#entityschema-schema-text');
//             } else if (headerText.includes('symbol')) {
  if (!$schemaText.length || !$schemaText.text().length) {
//                 if (setCellValue(row, values['symbol'])) filled++;
    return;
//            } else if (headerText === 'id' || headerText.includes(' id ')) {
  }
//                if (setCellValue(row, values['id'])) filled++;
 
//            }
  const listOfEntities = getListOfEntitiesFromSchemaText($schemaText.html());
//        });
  if (!listOfEntities.length) {
//
    return;
//        return filled;
  }
//     }
 
//
  requestEntitiesData(listOfEntities)
//     function showDebugFallback(values, errorText) {
    .then(function(responseData) {
//        const target = document.querySelector('#mw-content-text') || document.body;
      $schemaText.html(markupEntities($schemaText.html(), responseData));
//        if (!target) return;
    })
//
    .catch(function(error) {
//        const box = document.createElement('div');
      console.warn('Error in userscript: ' + scriptName);
//         box.style.border = '1px solid #c8ccd1';
      console.warn(error);
//        box.style.background = '#fff8e1';
    });
//         box.style.padding = '12px';
});
//         box.style.margin = '12px 0';
 
//         box.innerHTML = `
// Load EntityShape validator
//            <strong>QUDT-Testdaten</strong><br>
// --------------------------
//            ${errorText ? '<div style="color:#a33; margin-top:6px;">' + errorText + '</div>' : ''}
// Source: https://www.wikidata.org/wiki/User:Teester/EntityShape.js
//            <pre style="white-space:pre-wrap; margin-top:8px;"></pre>
/**
//        `;
* EntityShape.js adds an input box to a wikidata page wherein you can enter an entityschema
//        box.querySelector('pre').textContent = JSON.stringify(values, null, 2);
* (such as E10).  When you click "Check", checks whether each statement and property conforms
//         target.prepend(box);
* to the schema.  It then displays a summary at the top of the item for each property indicating
//    }
* whether they conform or not.  It also adds a badge to each statement and each property on the
//
* page indicating whether they conform or not.
//    fetch(apiUrl)
**/
//         .then(function (response) {
 
//             if (!response.ok) {
(function() {
//                throw new Error('HTTP ' + response.status);
    "use strict";
//             }
 
//             return response.json();
    mw.util.addCSS(entityschema_getStylesheet());
//        })
     let entityschema_list = [];
//        .then(function (data) {
     let value = mw.storage.get("entityschema-auto");
//            const values = extractValues(data);
    let schema = mw.storage.get("entityschema");
//            const filled = fillExistingTable(values);
    let lang = mw.config.get( 'wgUserLanguage' );
//
    let property_list = [];
//            if (filled === 0) {
 
//                showDebugFallback(values, 'Keine passende Property-Tabelle bzw. Zeile gefunden.');
    mw.hook( 'wikibase.entityPage.entityLoaded' ).add( function ( data ) {
//             }
         let valid_values = ['item', 'lexeme', 'property'];
//         })
         if (!valid_values.includes(data["type"])) { return; }
//         .catch(function (error) {
 
//            showDebugFallback({}, 'Fehler beim Laden: ' + error.message);
         mw.util.addSubtitle(entityschema_getHTML());
//         });
         $("#entityschema-checkbox").prop('checked', value);
// });
        $("#entityschema-schemaSearchButton").click(function(){ entityschema_update(); });
//
         $("#entityschema-checkbox").click(function() { entityschema_checkbox(); });
//
 
// /* =========================================================
        let claims = data["claims"];
//    Design
         for (let claim in claims) {
//    ========================================================= */
             property_list.push(claim);
// (function () {
             let statements = claims[claim];
//  function ready(fn) {
             for (let statement in statements) {
//    if (document.readyState !== "loading") fn();
                let mainsnak = statements[statement]["mainsnak"];
//    else document.addEventListener("DOMContentLoaded", fn);
                if (mainsnak["datavalue"] && mainsnak["datatype"] == "wikibase-item") {
//  }
                    if (!property_list.includes(mainsnak["datavalue"]["value"]["id"])) {
//
                        property_list.push(mainsnak["datavalue"]["value"]["id"]);
//  ready(function () {
                    }
//    enhanceExternalLinks();
                }
//    wrapWideTables();
             }
//    improveTOC();
         }
//    addCopyButtonsToCode();
         check_entity_for_schemas(property_list);
//    addBackToTop();
    });
//    improveSearchFocus();
 
//  });
    mw.hook( 'wikibase.statement.saved' ).add( function ( data ) {
//
         if (value == "true") {
//  function enhanceExternalLinks() {
            entityschema_update();
//    var links = document.querySelectorAll('#mw-content-text a[href^="http"]');
        }
//    links.forEach(function (link) {
    });
//      if (location.hostname && !link.href.includes(location.hostname)) {
 
//         link.setAttribute('target', '_blank');
    mw.hook( 'wikibase.statement.removed' ).add( function ( data ) {
//        link.setAttribute('rel', 'noopener noreferrer');
        if (value == "true") {
//         if (!link.querySelector('.sh-external-indicator')) {
            entityschema_update();
//          var mark = document.createElement('span');
        }
//          mark.className = 'sh-external-indicator';
    });
//          mark.setAttribute('aria-hidden', 'true');
 
//          mark.textContent = ' ↗';
    function check_entity_for_schemas(entity_list) {
//          link.appendChild(mark);
        const api = new mw.Api({'User-Agent': 'Userscript Entityshape by User:Teester'});
//         }
        for (let item in entity_list) {
//      }
            api.get({
//    });
                action: 'wbgetclaims',
//  }
                property: 'P12861',
//
                entity: entity_list[item],
//  function wrapWideTables() {
                format: 'json'})
//    var tables = document.querySelectorAll('.wikitable');
                .fail(function() { console.log("failed to get schemas") })
//    tables.forEach(function (table) {
                .done(function(data) {
//      if (table.parentElement && !table.parentElement.classList.contains('sh-table-wrap')) {
                    if (data["claims"].hasOwnProperty("P12861")) {
//        var wrap = document.createElement('div');
                        let claims = data["claims"]["P12861"];
//         wrap.className = 'sh-table-wrap';
                        for (let claim in claims) {
//        wrap.style.overflowX = 'auto';
                            entityschema_list.push(claims[claim]["mainsnak"]["datavalue"]["value"]["id"]);
//        wrap.style.margin = '1rem 0';
                        }
//         table.parentNode.insertBefore(wrap, table);
                    }
//         wrap.appendChild(table);
                });
//      }
        }
//     });
    }
//  }
 
//
    $(document).ajaxStop(function () {
//  function improveTOC() {
        if (entityschema_list.length != 0) {
//    var toc = document.querySelector('#toc, .toc');
            $('#entityschema-entityToCheck').attr("placeholder", entityschema_translate("Check against", entityschema_list.join(', ') ) );
//    if (!toc) return;
        }
//
        if (value == "true" && mw.config.get( 'wbEntityId' )) {
//    var title = toc.querySelector('.toctitle');
            entityschema_update();
//    var list = toc.querySelector('ul');
        }
//     if (!title || !list) return;
        $("#entityschema-entityToCheck:text").val(schema);
//
        $(this).unbind('ajaxStop');
//     var button = document.createElement('button');
    });
//     button.type = 'button';
 
//     button.className = 'sh-toc-toggle';
    $("#entityschema-entityToCheck").on("keyup", function(event){
//     button.textContent = 'Inhalt ein-/ausblenden';
        if (event.key === "Enter") {
//    button.style.marginTop = '0.5rem';
            event.preventDefault();
//    button.style.fontSize = '0.95rem';
            $("#entityschema-schemaSearchButton").click();
//    button.style.cursor = 'pointer';
            return false;
//
         }
//    button.addEventListener('click', function () {
    });
//      var hidden = list.style.display === 'none';
 
//      list.style.display = hidden ? '' : 'none';
    function entityschema_update() {
//    });
         let entityschema_entitySchema = $("#entityschema-entityToCheck")[0].value.toUpperCase();
//
        if (entityschema_entitySchema.length == 0) {
//    title.appendChild(button);
            entityschema_entitySchema = entityschema_list.join(", ");
//  }
            mw.storage.remove("entityschema");
//
         } else {
//  function addCopyButtonsToCode() {
            mw.storage.set("entityschema", entityschema_entitySchema);
//    var blocks = document.querySelectorAll('pre');
        }
//    blocks.forEach(function (block) {
        if (entityschema_entitySchema.length == 0) {
//      if (block.querySelector('.sh-copy-btn')) return;
            let message = new OO.ui.MessageWidget( {type: 'error', inline: true,
//
                label: entityschema_translate('No schemas entered and could not automatically determine schemas to check') } );
//      block.style.position = 'relative';
            $("#entityschema-response").empty().prepend( message.$element );
//
        } else {
//      var btn = document.createElement('button');
            let entityschema_entityName = document.location.pathname.substring(6);
//      btn.type = 'button';
            entityschema_checkEntity(entityschema_entityName, entityschema_entitySchema, lang);
//      btn.className = 'sh-copy-btn';
         }
//      btn.textContent = 'Kopieren';
    }
//       btn.style.position = 'absolute';
 
//       btn.style.top = '8px';
    function entityschema_checkbox() {
//      btn.style.right = '8px';
        if ($('#entityschema-checkbox').is(":checked")) {
//       btn.style.padding = '6px 10px';
            mw.storage.set("entityschema-auto", true);
//      btn.style.fontSize = '0.85rem';
         } else {
//      btn.style.borderRadius = '8px';
            mw.storage.set("entityschema-auto", false);
//
         }
//      btn.addEventListener('click', function () {
     }
//        var text = block.innerText;
 
//        navigator.clipboard.writeText(text).then(function () {
    function entityschema_checkEntity(entity, entitySchema, language) {
//          btn.textContent = 'Kopiert';
        $("#entityschema-response").contents().remove();
//          setTimeout(function () {
        $(".entityschema-property").remove();
//            btn.textContent = 'Kopieren';
        $(".entityschema-span").remove();
//          }, 1500);
 
//        });
        let url = "https://entityshape.toolforge.org/api/v2?entityschema=" + entitySchema + "&entity=" + entity + "&language=" + language;
//      });
        // let url = "http://127.0.0.1:5000/api/v2 ?entityschema=" + entitySchema + "&entity=" + entity + "&language=" + language;
//
        $.ajax({
//      block.appendChild(btn);
            type: "GET",
//    });
            dataType: "json",
//  }
            url: url,
//
            beforeSend: function() {
//  function addBackToTop() {
                $(".entityshape-spinner").show();
//     var btn = document.createElement('button');
            },
//     btn.type = 'button';
            success: function(data){
//     btn.textContent = '↑ Oben';
                for (let i = 0; i < data.schema.length; i++ ) {
//    btn.setAttribute('aria-label', 'Zurück nach oben');
                    if (data.properties[i]) {
//    btn.style.position = 'fixed';
                        entityschema_add_to_properties(data.properties[i], data.schema[i], data.name[i]);
//    btn.style.right = '16px';
                    }
//    btn.style.bottom = '16px';
                    if (data.statements[i]) {
//    btn.style.zIndex = '999';
                        entityschema_add_to_statements(data.statements[i], data.schema[i], data.name[i]);
//    btn.style.padding = '10px 14px';
                    }
//    btn.style.borderRadius = '999px';
                    if (data.general[i]) {
//    btn.style.display = 'none';
                        entityschema_add_general(data.general[i]);
//    btn.style.boxShadow = '0 8px 20px rgba(0,0,0,.15)';
                    }
//
                }
//     btn.addEventListener('click', function () {
 
//      window.scrollTo({ top: 0, behavior: 'smooth' });
                const combined_properties = entityschema_combine_properties(data.properties, data.schema);
//    });
 
//
                let message_data = [];
//    document.body.appendChild(btn);
                for (let schema in data.schema) {
//
                    message_data.push(`<a href='https://semantic-hub.io/wiki/EntitySchema:${data.schema[schema]}'>
//    window.addEventListener('scroll', function () {
                                      ${data.name[schema]} <small>(${data.schema[schema]})</small></a>`);
//      btn.style.display = window.scrollY > 500 ? 'block' : 'none';
                }
//    });
                let message = `${entityschema_translate('Checking against', message_data.join(', '))}:`;
//  }
 
//
                let message_widget = new OO.ui.MessageWidget( {type: 'notice', inline: true,
//  function improveSearchFocus() {
                                                        label: new OO.ui.HtmlSnippet( message )} );
//    var search = document.querySelector('#searchInput, input[name="search"]');
                $("#entityschema-response" ).append( message_widget.$element );
//    if (!search) return;
 
//
                let html = `<div style="overflow-y: scroll; max-height:200px;">
//    search.setAttribute('placeholder', 'Semantic Definition, semanticId oder Begriff suchen …');
                            <table style="width:100%;">
//
                            <th class="entityschema_table" title="${entityschema_translate('Properties in this item which must be present')}">${entityschema_translate("Required properties")}</th>
//    document.addEventListener('keydown', function (e) {
                            <th class="entityschema_table" title="${entityschema_translate('Properties in this item which can be present but do not have to be')}">${entityschema_translate("Optional properties")}</th>
//      if (e.key === '/' && document.activeElement !== search) {
                            <th class="entityschema_table" title="${entityschema_translate('Properties in this item which are not allowed to be present or not mentioned in the entityschema')}">${entityschema_translate("Other properties")}</th>
//        var tag = document.activeElement && document.activeElement.tagName;
                            <tr>`;
//        if (tag !== 'INPUT' && tag !== 'TEXTAREA') {
 
//          e.preventDefault();
                html += entityschema_process_combined_properties(combined_properties);
//          search.focus();
 
//        }
                $("#entityschema-response" ).append( html );
//      }
                $(".entityshape-spinner").hide();
//    });
            },
//  }
            error: function(data) {
// })();
                let message = new OO.ui.MessageWidget( {type: 'error', inline: true,
                                label: 'Unable to validate schema'} );
                $("#entityschema-response" ).append( message.$element );
                $(".entityshape-spinner").hide();
            }
        });
    }
 
     function entityschema_process_combined_properties(properties) {
        let required_html = '<td class="entityschema_table required"><ul style="list-style-type:none";>';
        let optional_html = '<td class="entityschema_table optional"><ul style="list-style-type:none";>';
        let absent_html = '<td class="entityschema_table absent"><ul style="list-style-type:none";>';
        let other_array = [];
        let other_array_names = [];
        for (let key in properties) {
            let shape_html = "";
            let response1 = properties[key].response.combined;
            let response_class  = "";
            let response_string = properties[key].response.combined;
            switch (response1) {
                case "present":
                    response_class = "present";
                    response_string = entityschema_translate("present");
                    break;
                case "allowed":
                    response_class = "present";
                    response_string = entityschema_translate("present");
                    break;
                case "correct":
                    response_class = "correct";
                    response_string = entityschema_translate("correct");
                    break;
                case "missing":
                    response_class = "missing";
                    response_string = entityschema_translate("missing");
                    break;
                default:
                    response_class = "wrong";
                    response_string = entityschema_translate("wrong");
                    break;
            }
            if (properties[key].necessity.combined == "absent") {
                if (response1 == "too many statements") {
                    response1 = "not allowed";
                    response_string = entityschema_translate("not allowed");
                }
            }
            if (!response1) {
                response1 = "Not in schema";
                response_string = entityschema_translate("Not in schema");
                response_class = "notinschema";
            }
            let schema_link = `<span class="wb-itemlink"><span class="wb-itemlink-label" lang="en" dir="ltr">${properties[key].name}</span> <span class="wb-itemlink-id">(${key})</span></span>`;
            if (response1 == null) {
                response1 = "";
                shape_html += `<a href="https://semantic-hub.io/wiki/Property:${key}">${schema_link}</a><br/>`;
            } else if (response1 == "Not in schema") {
                other_array.push(key);
                other_array_names.push(schema_link);
            } else {
                shape_html += `<li class="is_entityschema-${response_class}">
                              <span class="entityschema-span entityschema-${response_class}">${response_string}</span>
                              <a href="https://semantic-hub.io/wiki/Property:${key}"
                                  class="is_entityschema-${response_class}">
                              ${schema_link}</a></li>`;
            }
            switch (properties[key].necessity.combined) {
                case "required":
                    required_html += shape_html;
                    break;
                case "optional":
                    optional_html += shape_html;
                    break;
                default:
                    absent_html += shape_html;
                    break;
            }
        }
        let other_html = `<details><summary>${entityschema_translate("properties not in any schema checked", other_array.length)} </summary>
                          <ul style='list-style-type:none';>`;
        for (let item in other_array) {
            other_html += `<li><span class="entityschema-span entityschema-notinschema">${entityschema_translate("Not in schema")}</span>
                              <a href="https://semantic-hub.io/wiki/Property:${other_array[item]}"
                                  class="is_entityschema-notinschema">${other_array_names[item]}</a></li>`;
        }
        other_html += "</ul></details>";
        absent_html += "</ul>" + other_html;
        required_html += "</ul></td>";
        optional_html += "</ul></td>";
        absent_html += "</td>";
        let html = required_html + optional_html + absent_html + '</tr></table></div>';
        return html;
    }
 
    function entityschema_add_to_properties(properties, schema, name) {
        for (let key in properties) {
          let response = properties[key].response;
          let response_class = "";
            switch (response) {
                case "present":
                    response_class = "present";
                    break;
                case "correct":
                    response_class = "correct";
                    break;
                case "missing":
                    response_class = "missing";
                    break;
                default:
                    response_class = "wrong";
                    break;
            }
            if (properties[key].necessity == "absent") {
                if (response == "too many statements") {
                    response = "not allowed";
                }
            }
            if (!response) {
                response = "Not in schema";
                response_class = "notinschema";
            }
            if (response == null) {
                response = "Not in schema";
                response_class = "notinschema";
            }
            if (response != "Not in schema" && $("#" + key)[0]) {
                let html =`<br class='entityschema-property'/>
                          <div style='display:inline-block;'
                                class='entityschema-span entityschema-property entityschema-${response_class}'
                                title='${schema}: ${name}'>${schema}: ${response}
                          </div>`;
                $(`#${key} .wikibase-statementgroupview-property-label`).append(html);
            }
        }
    }
 
    function entityschema_add_to_statements(statements, schema, name) {
        for (let statement in statements) {
            let response = statements[statement].response;
            if (response != "not in schema") {
                let html = `<br class='entityschema-property'/>
                            <span class='entityschema-span entityschema-property entityschema-${response}'
                                  title='${schema}: ${name}'>${schema}: ${response}
                            </span>`;
                $(`div[id='${statement}'] .wikibase-toolbar-button-edit`).append(html);
            }
        }
    }
 
    function entityschema_add_general(general) {
        if (general.language) {
            entityschema_add_general_item("language", general.language);
        }
        if (general.lexicalCategory) {
            entityschema_add_general_item("lexical_category", general.lexicalCategory);
        }
    }
 
    function entityschema_add_general_item(general_type, response) {
        if (response != "not in schema") {
            html = `<span class='entityschema-property'/>
                    <span class='entityschema-span entityschema-property entityschema-${response}'>${response}
                    </span>`;
            $(`span[class='language-lexical-category-${general_type}']`).append(html);
        }
    }
 
    function entityschema_combine_properties(property, schema) {
        let combined_properties = {};
        for (let i = 0; i < schema.length; i++ ) {
            for (let key in property[i]) {
              if(!combined_properties.hasOwnProperty(key)){ combined_properties[key] = {}; }
              combined_properties[key]["name"] = property[i][key]["name"];
              if(!combined_properties[key].hasOwnProperty("response")) { combined_properties[key]["response"] = {}; }
              combined_properties[key]["response"][schema[i]] = property[i][key]["response"];
              if(!combined_properties[key].hasOwnProperty("necessity")) { combined_properties[key]["necessity"] = {}; }
              combined_properties[key]["necessity"][schema[i]] = property[i][key]["necessity"];
            }
        }
        for (let key in combined_properties) {
            let necessity = "absent";
            let response = "";
            let response_key = combined_properties[key]["response"];
            let necessity_key = combined_properties[key]["necessity"];
 
            if (Object.values(necessity_key).includes("required")) {
                necessity = "required";
            } else if (Object.values(necessity_key).includes("optional")) {
                necessity = "optional";
            }
 
            if (Object.values(response_key).includes("incorrect")) {
                response = "incorrect";
            } else if (Object.values(response_key).includes("missing")) {
                response = "missing";
            } else if (Object.values(response_key).includes("too many statements")) {
                response = "too many statements";
            } else if (Object.values(response_key).includes("not enough statements")) {
                response = "not enough statements";
            } else if (Object.values(response_key).includes("correct")) {
                response = "correct";
            } else if (Object.values(response_key).includes("present")) {
                response = "present";
            } else if (Object.values(response_key).includes("allowed")) {
                response = "present";
            }
            combined_properties[key]["response"]["combined"] = response;
            combined_properties[key]["necessity"]["combined"] = necessity;
        }
        return combined_properties;
    }
 
    function entityschema_translate(phrase, variable="") {
        const translations = {
            "en": {
                // Strings in the checking UI
                "Enter schema to check against": "Enter schema to check against e.g. E234",
                "Check against entityschema": "Check against entityschema",
                "Check against" : `Check against ${variable}`,
                "Checking against": `Checking against ${variable}`,
                "Check": "Check",
                "Automatically check schema": "Automatically check schema",
                "Unable to validate schema": "Unable to validate schema",
                "No schemas entered and could not automatically determine schemas to check": "No schemas entered and could not automatically determine schemas to check",
                // Strings in the results section UI
                "Properties in this item which must be present": "Properties in this item which must be present",
                "Required properties": "Required properties",
                "Properties in this item which can be present but do not have to be": "Properties in this item which can be present but do not have to be",
                "Optional properties": "Optional properties",
                "Properties in this item which are not allowed to be present or not mentioned in the entityschema": "Properties in this item which are not allowed to be present or not mentioned in the entityschema",
                "Other properties": "Other properties",
                "properties not in any schema checked": `${variable} properties not in any schema checked`,
                // Strings for results
                "present": "present",
                "correct": "correct",
                "missing": "missing",
                "wrong": "wrong",
                "absent": "absent",
                "too many statements": "too many statements",
                "not allowed": "not allowed",
                "Not in schema": "Not in schema"
            },
            "ga": {
                // Strings in the checking UI
                "Enter schema to check against": "Cuir scéima isteach chun seiceáil m.sh. E234",
                "Check against entityschema": "Seiceáil trí scéim eintitis",
                "Check against" : `Seiceáil trí ${variable}`,
                "Checking against": `Ag seiceáil trí ${variable}`,
                "Check": "Seiceáil",
                "Automatically check schema": "Seiceáil scéima go huathoibríoch",
                "Unable to validate schema": "Ní féidir scéima bailíochtú",
                "No schemas entered and could not automatically determine schemas to check": "Níor iontráladh aon scéimeanna agus níorbh fhéidir scéimeanna le seiceáil a chinneadh go huathoibríoch",
                // Strings in the results section UI
                "Properties in this item which must be present": "Airíonna sa mhír seo nach mór a bheith i láthair",
                "Required properties": "Airíonna riachtanacha",
                "Properties in this item which can be present but do not have to be": "Airíonna sa mhír seo a fhéadfaidh a bheith i láthair ach nach gá a bheith ann",
                "Optional properties": "Airíonna roghnacha",
                "Properties in this item which are not allowed to be present or not mentioned in the entityschema": "Airíonna sa mhír seo nach gceadaítear dóibh a bheith i láthair nó nach luaitear sa scéim eintitis",
                "Other properties": "Airíonna eile",
                "properties not in any schema checked": `Bhí ${variable} airíonna nach raibh in aon scéim seicáilte`,
                // Strings for results
                "present": "ann",
                "correct": "ceart",
                "missing": "ar iarraidh",
                "wrong": "míceart",
                "absent": "as lathair",
                "too many statements": "an iomarca ráiteas",
                "not allowed": "ní cheadaítear",
                "Not in schema": "ní sa scéim"
            }
        };
        let language = "en";
        if (translations.hasOwnProperty(lang)) {
            language = lang;
        }
        return translations[language][phrase];
    }
 
    function entityschema_getStylesheet() {
        const entityschema_stylesheet = `#entityschema-simpleSearch { width:500px; }
                                        #entityschema-response { padding:5px; display: block; }
                                        .entityschema-summary  { color: var(--color-progressive,#0645ad); }
                                        a.is_entityschema-present { color: #008800; }
                                        a.is_entityschema-allowed { color: #008800; }
                                        a.is_entityschema-correct { color: #00CC00; }
                                        a.is_entityschema-missing { color: #FF5500; }
                                        a.is_entityschema-notinschema { color: #FF5500; }
                                        a.is_entityschema-wrong { color: #CC0000; }
                                        a.is_entityschema-wrong_amount { color: #CC0000; }
                                        a.is_entityschema-incorrect { color: #CC0000; }
                                        .entityschema_table {vertical-align: top; width: 33%; }
                                        .entityschema-missing { background-color: #FF8C00; }
                                        .entityschema-notinschema { background-color: #FF8C00; }
                                        .entityschema-wrong { background-color: #CC0000; }
                                        .entityschema-incorrect { background-color: #CC0000; }
                                        .entityschema-wrong_amount { background-color: #CC0000; }
                                        .entityschema-excess { background-color: #CC0000; }
                                        .entityschema-deficit { background-color: #CC0000; }
                                        .entityschema-present { background-color: #008800; }
                                        .entityschema-allowed { background-color: #008800; }
                                        .entityschema-correct { background-color: #00CC00; }
                                        .required .entityschema-missing { background-color: #FF0000;}
                                        .required a.is_entityschema-missing { color: #FF0000;}
                                        .absent .entityschema-missing { display: none;}
                                        .absent a.is_entityschema-missing { display: none;}
                                        .entityschema-span { color: #ffffff; padding:2px; margin: 2px; font-size:75%; border-radius:2px; }
                                        .entityshape-spinner,.entityshape-spinner div,.entityshape-spinner div:after {box-sizing: border-box;}
                                        .entityshape-spinner { padding-top:5px; padding-bottom:5px; color: currentColor; display: inline-block; position: relative; width: 20px; height: 20px;}
                                        .entityshape-spinner div { transform-origin: 10px 10px; animation: entityshape-spinner 1.2s linear infinite;}
                                        .entityshape-spinner div:after { content: " "; display: block; position: absolute; top: 0.8px; left: 9.2px; width: 1.6px; height: 4.4px; border-radius: 20%; background: currentColor;}
                                        .entityshape-spinner div:nth-child(1) { transform: rotate(0deg); animation-delay: -1.1s;}
                                        .entityshape-spinner div:nth-child(2) { transform: rotate(30deg); animation-delay: -1s;}
                                        .entityshape-spinner div:nth-child(3) { transform: rotate(60deg); animation-delay: -0.9s;}
                                        .entityshape-spinner div:nth-child(4) { transform: rotate(90deg); animation-delay: -0.8s;}
                                        .entityshape-spinner div:nth-child(5) { transform: rotate(120deg); animation-delay: -0.7s;}
                                        .entityshape-spinner div:nth-child(6) { transform: rotate(150deg); animation-delay: -0.6s;}
                                        .entityshape-spinner div:nth-child(7) { transform: rotate(180deg); animation-delay: -0.5s;}
                                        .entityshape-spinner div:nth-child(8) { transform: rotate(210deg); animation-delay: -0.4s;}
                                        .entityshape-spinner div:nth-child(9) { transform: rotate(240deg); animation-delay: -0.3s;}
                                        .entityshape-spinner div:nth-child(10) { transform: rotate(270deg); animation-delay: -0.2s;}
                                        .entityshape-spinner div:nth-child(11) { transform: rotate(300deg); animation-delay: -0.1s;}
                                        .entityshape-spinner div:nth-child(12) { transform: rotate(330deg); animation-delay: 0s;}
                                        @keyframes entityshape-spinner { 0% { opacity: 1; } 100% { opacity: 0; }}`;
        return entityschema_stylesheet;
    }
 
    function entityschema_getHTML() {
        const entityschema_results_html = `<details open style='box-shadow: 0 1px var(--border-color-subtle,#c8ccd1);'>
                                          <summary class='entityschema-summary'>${entityschema_translate("Check against entityschema")}</summary>
                                          <div class="oo-ui-layout oo-ui-horizontalLayout">
                                              <div class="oo-ui-layout oo-ui-fieldLayout oo-ui-fieldLayout-align-top oo-ui-actionFieldLayout">
                                                  <div class="oo-ui-fieldLayout-body">
                                                      <div id="entityschema-simpleSearch" class="oo-ui-fieldLayout-field">
                                                          <div class="oo-ui-actionFieldLayout-input">
                                                              <div class="oo-ui-widget oo-ui-widget-enabled oo-ui-inputWidget oo-ui-textInputWidget oo-ui-textInputWidget-type-text">
                                                                  <input type="text" tabindex="0" class="oo-ui-inputWidget-input" value="" id="entityschema-entityToCheck" placeholder="${entityschema_translate("Enter schema to check against")}">
                                                              </div>
                                                          </div>
                                                          <span class="oo-ui-actionFieldLayout-button" id="entityschema-schemaSearchButton">
                                                              <span class="oo-ui-widget oo-ui-widget-enabled oo-ui-buttonElement oo-ui-buttonElement-framed oo-ui-labelElement oo-ui-buttonWidget">
                                                                  <a class="oo-ui-buttonElement-button" role="button" tabindex="0" rel="nofollow">
                                                                      <span class="oo-ui-labelElement-label">${entityschema_translate("Check")}</span>
                                                                  </a>
                                                              </span>
                                                          </span>
                                                      </div>
                                                  </div>
                                              </div>
                                              <div class="entityshape-spinner" style="display:none"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div>
                                              <div class="oo-ui-layout oo-ui-labelElement oo-ui-fieldLayout oo-ui-fieldLayout-align-inline">
                                                  <div class="oo-ui-fieldLayout-body">
                                                      <span class="oo-ui-fieldLayout-field">
                                                          <span class="oo-ui-widget oo-ui-widget-enabled oo-ui-inputWidget oo-ui-checkboxInputWidget">
                                                              <input type="checkbox" tabindex="0" class="oo-ui-inputWidget-input" value="" id="entityschema-checkbox">
                                                              <span class="oo-ui-checkboxInputWidget-checkIcon oo-ui-widget oo-ui-widget-enabled oo-ui-iconElement oo-ui-iconElement-icon oo-ui-icon-check oo-ui-labelElement-invisible oo-ui-iconWidget oo-ui-image-invert">
                                                              </span>
                                                          </span>
                                                      </span>
                                                      <span class="oo-ui-fieldLayout-header">
                                                          <label class="oo-ui-labelElement-label">${entityschema_translate("Automatically check schema")}</label>
                                                      </span>
                                                  </div>
                                              </div>
                                          </div>
                                          <span id="entityschema-response"></span></details>`;
        return entityschema_results_html;
    }
}());

Latest revision as of 21:31, 23 April 2026

mw.loader.load('/w/index.php?title=MediaWiki:CustomExtensions&action=raw&ctype=text/javascript');

// Note: I had to comment out the following parts since it crashed the global JS
//       23.04.26, 23:30 P.Wagner (FoP Consult)

// mw.loader.using(['mediawiki.util']).then(function () {
//     if (mw.config.get('wgPageName') !== 'Item:Q5' || mw.config.get('wgAction') !== 'view') {
//         return;
//     }
// 
//     const apiUrl = 'http://127.0.0.1:5000/api/v3/search?search=Volt&lang=en&types=unit';
// 
//     function normalizeText(text) {
//         return (text || '')
//             .replace(/\s+/g, ' ')
//             .trim()
//             .toLowerCase();
//     }
// 
//     function extractValues(data) {
//         const result = data?.result || {};
//         const embedded = (result.embeddedDataSpecifications || [])[0] || {};
//         const content = embedded.dataSpecificationContent || {};
// 
//         const preferredNameRaw = content.preferredName?.value;
//         const symbolRaw = content.Symbol?.value;
// 
//         let preferredName = '—';
//         if (Array.isArray(preferredNameRaw)) {
//             preferredName = preferredNameRaw
//                 .map(v => typeof v === 'object' && v !== null ? (v.value || JSON.stringify(v)) : String(v))
//                 .join(', ');
//         } else if (preferredNameRaw) {
//             preferredName = typeof preferredNameRaw === 'object'
//                 ? (preferredNameRaw.value || JSON.stringify(preferredNameRaw))
//                 : String(preferredNameRaw);
//         }
// 
//         let symbol = '—';
//         if (symbolRaw) {
//             symbol = typeof symbolRaw === 'object'
//                 ? (symbolRaw.value || JSON.stringify(symbolRaw))
//                 : String(symbolRaw);
//         }
// 
//         return {
//             'id': result.id || '—',
//             'idshort': result.idShort || '—',
//             'preferred name': preferredName,
//             'preferredname': preferredName,
//             'symbol': symbol
//         };
//     }
// 
//     function setCellValue(row, value) {
//         if (!row) return false;
// 
//         let valueCell =
//             row.querySelector('td') ||
//             row.querySelector('.wikibase-statementview-mainsnak-container') ||
//             row.querySelector('.wikibase-snakview-value') ||
//             row.querySelector('.wikibase-statementview-mainsnak');
// 
//         if (!valueCell) return false;
// 
//         const target =
//             valueCell.querySelector('.wikibase-snakview-value') ||
//             valueCell;
// 
//         target.textContent = value;
//         return true;
//     }
// 
//     function fillExistingTable(values) {
//         const rows = document.querySelectorAll('tr, .wikibase-statementview');
// 
//         let filled = 0;
// 
//         rows.forEach(function (row) {
//             const headerText = normalizeText(row.textContent);
// 
//             if (!headerText) return;
// 
//             if (headerText.includes('idshort')) {
//                 if (setCellValue(row, values['idshort'])) filled++;
//             } else if (headerText.includes('preferred name') || headerText.includes('preferredname')) {
//                 if (setCellValue(row, values['preferredname'])) filled++;
//             } else if (headerText.includes('symbol')) {
//                 if (setCellValue(row, values['symbol'])) filled++;
//             } else if (headerText === 'id' || headerText.includes(' id ')) {
//                 if (setCellValue(row, values['id'])) filled++;
//             }
//         });
// 
//         return filled;
//     }
// 
//     function showDebugFallback(values, errorText) {
//         const target = document.querySelector('#mw-content-text') || document.body;
//         if (!target) return;
// 
//         const box = document.createElement('div');
//         box.style.border = '1px solid #c8ccd1';
//         box.style.background = '#fff8e1';
//         box.style.padding = '12px';
//         box.style.margin = '12px 0';
//         box.innerHTML = `
//             <strong>QUDT-Testdaten</strong><br>
//             ${errorText ? '<div style="color:#a33; margin-top:6px;">' + errorText + '</div>' : ''}
//             <pre style="white-space:pre-wrap; margin-top:8px;"></pre>
//         `;
//         box.querySelector('pre').textContent = JSON.stringify(values, null, 2);
//         target.prepend(box);
//     }
// 
//     fetch(apiUrl)
//         .then(function (response) {
//             if (!response.ok) {
//                 throw new Error('HTTP ' + response.status);
//             }
//             return response.json();
//         })
//         .then(function (data) {
//             const values = extractValues(data);
//             const filled = fillExistingTable(values);
// 
//             if (filled === 0) {
//                 showDebugFallback(values, 'Keine passende Property-Tabelle bzw. Zeile gefunden.');
//             }
//         })
//         .catch(function (error) {
//             showDebugFallback({}, 'Fehler beim Laden: ' + error.message);
//         });
// });
// 
// 
// /* =========================================================
//    Design
//    ========================================================= */
// (function () {
//   function ready(fn) {
//     if (document.readyState !== "loading") fn();
//     else document.addEventListener("DOMContentLoaded", fn);
//   }
// 
//   ready(function () {
//     enhanceExternalLinks();
//     wrapWideTables();
//     improveTOC();
//     addCopyButtonsToCode();
//     addBackToTop();
//     improveSearchFocus();
//   });
// 
//   function enhanceExternalLinks() {
//     var links = document.querySelectorAll('#mw-content-text a[href^="http"]');
//     links.forEach(function (link) {
//       if (location.hostname && !link.href.includes(location.hostname)) {
//         link.setAttribute('target', '_blank');
//         link.setAttribute('rel', 'noopener noreferrer');
//         if (!link.querySelector('.sh-external-indicator')) {
//           var mark = document.createElement('span');
//           mark.className = 'sh-external-indicator';
//           mark.setAttribute('aria-hidden', 'true');
//           mark.textContent = ' ↗';
//           link.appendChild(mark);
//         }
//       }
//     });
//   }
// 
//   function wrapWideTables() {
//     var tables = document.querySelectorAll('.wikitable');
//     tables.forEach(function (table) {
//       if (table.parentElement && !table.parentElement.classList.contains('sh-table-wrap')) {
//         var wrap = document.createElement('div');
//         wrap.className = 'sh-table-wrap';
//         wrap.style.overflowX = 'auto';
//         wrap.style.margin = '1rem 0';
//         table.parentNode.insertBefore(wrap, table);
//         wrap.appendChild(table);
//       }
//     });
//   }
// 
//   function improveTOC() {
//     var toc = document.querySelector('#toc, .toc');
//     if (!toc) return;
// 
//     var title = toc.querySelector('.toctitle');
//     var list = toc.querySelector('ul');
//     if (!title || !list) return;
// 
//     var button = document.createElement('button');
//     button.type = 'button';
//     button.className = 'sh-toc-toggle';
//     button.textContent = 'Inhalt ein-/ausblenden';
//     button.style.marginTop = '0.5rem';
//     button.style.fontSize = '0.95rem';
//     button.style.cursor = 'pointer';
// 
//     button.addEventListener('click', function () {
//       var hidden = list.style.display === 'none';
//       list.style.display = hidden ? '' : 'none';
//     });
// 
//     title.appendChild(button);
//   }
// 
//   function addCopyButtonsToCode() {
//     var blocks = document.querySelectorAll('pre');
//     blocks.forEach(function (block) {
//       if (block.querySelector('.sh-copy-btn')) return;
// 
//       block.style.position = 'relative';
// 
//       var btn = document.createElement('button');
//       btn.type = 'button';
//       btn.className = 'sh-copy-btn';
//       btn.textContent = 'Kopieren';
//       btn.style.position = 'absolute';
//       btn.style.top = '8px';
//       btn.style.right = '8px';
//       btn.style.padding = '6px 10px';
//       btn.style.fontSize = '0.85rem';
//       btn.style.borderRadius = '8px';
// 
//       btn.addEventListener('click', function () {
//         var text = block.innerText;
//         navigator.clipboard.writeText(text).then(function () {
//           btn.textContent = 'Kopiert';
//           setTimeout(function () {
//             btn.textContent = 'Kopieren';
//           }, 1500);
//         });
//       });
// 
//       block.appendChild(btn);
//     });
//   }
// 
//   function addBackToTop() {
//     var btn = document.createElement('button');
//     btn.type = 'button';
//     btn.textContent = '↑ Oben';
//     btn.setAttribute('aria-label', 'Zurück nach oben');
//     btn.style.position = 'fixed';
//     btn.style.right = '16px';
//     btn.style.bottom = '16px';
//     btn.style.zIndex = '999';
//     btn.style.padding = '10px 14px';
//     btn.style.borderRadius = '999px';
//     btn.style.display = 'none';
//     btn.style.boxShadow = '0 8px 20px rgba(0,0,0,.15)';
// 
//     btn.addEventListener('click', function () {
//       window.scrollTo({ top: 0, behavior: 'smooth' });
//     });
// 
//     document.body.appendChild(btn);
// 
//     window.addEventListener('scroll', function () {
//       btn.style.display = window.scrollY > 500 ? 'block' : 'none';
//     });
//   }
// 
//   function improveSearchFocus() {
//     var search = document.querySelector('#searchInput, input[name="search"]');
//     if (!search) return;
// 
//     search.setAttribute('placeholder', 'Semantic Definition, semanticId oder Begriff suchen …');
// 
//     document.addEventListener('keydown', function (e) {
//       if (e.key === '/' && document.activeElement !== search) {
//         var tag = document.activeElement && document.activeElement.tagName;
//         if (tag !== 'INPUT' && tag !== 'TEXTAREA') {
//           e.preventDefault();
//           search.focus();
//         }
//       }
//     });
//   }
// })();