User:Inductiveload/topic matcher.js

From Wikisource
Jump to navigation Jump to search
Note: After saving, changes may not occur immediately. Click here to learn how to bypass your browser's cache.
  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Cmd-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (Cmd-Shift-R on a Mac)
  • Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Clear the cache in Tools → Preferences

For details and instructions about other browsers, see Wikipedia:Bypass your cache.

// ==================================================================
// topic_matcher.js
//
// Adds a link to the topicmatcher.toolforge.org tool, if the current item
// does have a Wikidata item and does not have any main subject (P921) set.
//
// Usage is something like:
//
// mw.loader.load("//en.wikisource.org/w/index.php?title=User:Inductiveload/topic_matcher.js&action=raw&ctype=text/javascript");
//
// (wrap in a check for wgTitle or similar if you want to restrict pages it
// runs on)
//
// Configuration hook:
//
//  mw.hook("topic_matcher.config").add(function(cfg) {
//    cfg.notify_has_topics = false;
//  });
//
// Options:
//  * notify_has_topics: pop a notification if the WD item exists and has topics
// Changelog: 2021-02-09: Initial version
// ==================================================================


(function($, mw) {

  "strict";

  var TopicMatcher = {
    signature: "topic_matcher",
    strings: {
      link_tooltip: 'Match topic',
      link_text: 'Add topic',
    },
    cfg: {
      notify_has_topics: true,
    }
  };

  var PROPS = {
    main_subject: "P921",
  }

  function add_topicmatcher_link(qid) {
    $("<a>")
      .append(TopicMatcher.strings.link_text)
      .appendTo(".mw-indicators")
      .addClass("wd-tools")
      .attr({
        title: TopicMatcher.strings.link_tooltip,
        href: "https://topicmatcher.toolforge.org/#/random/?q=" + qid,
        id: 'wd-tool-topicmatch'
      });
  }

  function wd_entity_link(qid) {
    return $("<a>")
      .attr("href", "https://www.wikidata.org/wiki/" + qid)
      .append(qid);
  }

  function append_links(links, $target) {
    links.forEach(function(l, i) {
      $target.append(l);
      if (i < links.length - 1) {
        $target.append(", ");
      }
    });
  }

  function notify_topics_exist(main_subjects) {
    var ms_links = main_subjects
      .map(function(ms) {
        return wd_entity_link(ms.mainsnak.datavalue.value.id);
      });

    var text = (ms_links.length === 1)
        ? "Item has a main subject" : "Item has main subjects";

    var $content = $("<span>").append(text + ": ");
    append_links(ms_links, $content);

    mw.notify($content);
  }

  /*
   * Get a property claim for a given entity.
   *
   * Returns a promise which resolves with that property's claim (or null)
   */
  function wd_get_claim_promise(qid, property) {
    var params = {
      action: "wbgetclaims",
      entity: qid,
      property: property,
      format: "json",
    };

    var api = new mw.ForeignApi('https://www.wikidata.org/w/api.php');
    return api.get(params)
      .then(function(data) {
        return data.claims[property];
      });
  }

  function initialise() {
    // fire the config hook
    mw.hook(TopicMatcher.signature + ".config")
      .fire(TopicMatcher.cfg);

    var qid = mw.config.get("wgWikibaseItemId");

    if (qid) {
      wd_get_claim_promise(qid, PROPS.main_subject)
        .then(function(main_subjects){

          if (!main_subjects || main_subjects.length === 0) {
            add_topicmatcher_link(qid);
          } else if (TopicMatcher.cfg.notify_has_topics) {
            notify_topics_exist(main_subjects)
          };
        });
    } else {
      // at this point an item creator might kick in (or maybe that's a different gadget)
    }
  }

  mw.loader.using([
      'mediawiki.util', 'mediawiki.api', 'mediawiki.ForeignApi',
    ], function() {
      $(initialise);
    }
  );

}(jQuery, mediaWiki));