User:Btwashburn/iiif-mirador.js

From Wikidata
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/*******************************************************************************
********************************************************************************
**                                                                            **
**     iiif-mirador.js                                                        **
**                                                                            **
**     Add Project Mirador's IIIF Manifest Viewer to Wikidata item pages      **
**                                                                            **
** -------------------------------------------------------------------------- **
**                                                                            **
**  INSTALLATION                                                              **
**                                                                            **
**   - Create a Wikidata user account if you don't already have one.          **
**                                                                            **
**   - Logon to Wikidata.                                                     **
**                                                                            **
**   - Add the "importScript" shown below to your common Javascript page at   **
**     https://www.wikidata.org/wiki/Special:MyPage/common.js                 **
**                                                                            **
**     importScript( 'User:Btwashburn/iiif-mirador.js' );                     **
**                                                                            **
**  WIKIDATA ITEMS FOR DEMONSTRATION                                          **
**                                                                            **
**   - Example Wikidata items that include a IIIF manifest statement and that **
**     will display the Mirador viewer, if this user script is added:         **
**                                                                            **
**     https://www.wikidata.org/wiki/Q1192436                                 **
**     https://www.wikidata.org/wiki/Q2395218                                 **
**                                                                            **
**   - Find more examples by scanning the list of Wikidata items on the       **
**     "IIIF manifest" property's "what links here" page:                     **
**                                                                            **
**     https://www.wikidata.org/wiki/Special:WhatLinksHere/Property:P6108     **
**                                                                            **
**   - As of March 2021 there were over 165,000 IIIF manifest statements in   **
**     Wikidata.  The Wikidata Query service can return their associated      **
**     items and URLs:  https://w.wiki/37FJ                                   **
**                                                                            **
**  HOW IT WORKS                                                              **
**                                                                            **
**   - This script modifies the Wikidata item display, if the item includes   **
**     one or more "IIIF manifest" statements, to embed Project Mirador's     **
**     IIIF presentation manifest viewer.                                     **
**                                                                            **
**   - IIIF manifest statements are detected by their Wikidata Property       **
**     identifier, P6108.                                                     **
**                                                                            **
**   - The IIIF Manifest URL is extracted from the Property statement, and    **
**     a Project Mirador URL to embed the Mirador viewer for that URL is      **
**     constructed.                                                           **
**                                                                            **
**   - An HTML iframe element is created and added to the Wikidata item page  **
**     DOM, and its src attribute is given the Project Mirador embed URL.     **
**                                                                            **
**  KNOWN ISSUES                                                              **
**                                                                            **
**   - Some IIIF Manifest URLs use the "http" protocol, rather than           **
**     "https", which would prevent the embedded viewer from loading in       **
**     some web browsers, due to a "mixed content" security constraint.       **
**     For example:  https://www.wikidata.org/wiki/Q18573749                  **
**     The script checks the protocol and changes http to https, which can    **
**     allow it to be resolved (in some cases).                               **
**                                                                            **
**   - Some IIIF Manifest URLs do not return a JSON manifest, for example     **
**     the url in https://www.wikidata.org/wiki/Q1171095. The embedded        **
**     viewer is presented without content, and links to the full Mirador     **
**     view open the viewer without content.                                  **
**                                                                            **
********************************************************************************
*******************************************************************************/

( function ( mw, $ ) {
  "use strict";

  // Set script variables

  // Properties associated with the IIIF Manifest
  var iiif = {
    "logo": {
      "url": "https://iiif.io/img/logo-iiif-34x30.png",
      "text": "IIIF logo",
      "style": "margin-right: 6px; height: 20px;"
    },
    "parent": "",
    "pcode": "P6108"
  };

  // Image for the IIIF logo
  var $iiifLogo = $( '<img/>', {
    "src": iiif.logo.url,
    "title": iiif.logo.text,
    "alt": iiif.logo.text,
    "style": iiif.logo.style
  });

  // Span object and link for the IIIF Manifest viewer provider
  var viewerProviderProperties = {
    "prefix": "IIIF Presentation Manifest viewer provided by ",
    "title": "Project Mirador",
    "href": "https://projectmirador.org/",
    "logo": {
      "url": "https://projectmirador.org/img/mirador-logo.svg",
      "text": "Project Mirador logo",
      "style": "margin-right: 6px; height: 20px;"
    }
  };
  var $viewerProvider = $("<span/>")
    .append(viewerProviderProperties.prefix)
    .append($("<a/>", {
    "target" : "_blank",
    "href" : viewerProviderProperties.href,
    "title": viewerProviderProperties.title,
    "text" : viewerProviderProperties.title
  }));
  // Image for the IIIF manifest viewer logo
  var $viewerProviderLogo = $( '<img/>', {
    "src": viewerProviderProperties.logo.url,
    "title": viewerProviderProperties.logo.text,
    "alt": viewerProviderProperties.logo.text,
    "style": viewerProviderProperties.logo.style
  });

  // Define how to select an HTML DOM element where the viewer will be embedded
  var selector = "#toc:first";

  // Set the host systems that will return the HTML source for the viewer
  var embeddedViewerHost = "https://projectmirador.org/embed/?iiif-content=";
  var fullViewerHost = "https://projectmirador.org/embed/?iiif-content=";

  // Initialize the IIIF manifest URL
  var manifestUrl = "";

  // Initialization function
  function init() {

    // If the HTML DOM has an element id for the IIIF Manifest URL Property code
    if ( $("#" + iiif.pcode ).length ) {

      // Get the parent div for the IIIF Manifest URL Property code identifier
      iiif.parent = $("#" + iiif.pcode);

      // For each wikibase-snakview-value href in the iiif.parent ...
      var snakview = ".wikibase-snakview-value > a[href]:first";
      $(snakview, iiif.parent).each( function () {

        // Get the IIIF manifest URL from the statement
        var $thisStatement = $( this );
        manifestUrl = $thisStatement.attr("href");

        // Change the link protocol to "https" if it's "http".
        if (manifestUrl.substring(0,5) == "http:") {
          manifestUrl = manifestUrl.replace("http:","https:");
        }

        // Construct a URLs to fetch the Mirador3 viewer and the Manifest
        var embeddedViewerUrl = embeddedViewerHost + manifestUrl;
        var fullViewerUrl = fullViewerHost + manifestUrl;

        // Construct an iframe for the embedded viewer
        var viewerStyle = "width: 100%; height: 640px; border: 0px; margin: 0px; padding: 0px;"
        var $viewer = $("<iframe/>", {
          "id": "viewer",
          "style": viewerStyle,
          "src": embeddedViewerUrl
        });

        // Construct a link to an external IIIF viewer of the manifest URL
        var externalViewerProperties = {
          "title": "See a full view in a new browser window.",
          "text": "Full view"
        };
        var $externalViewerLink = $("<a/>", {
          "target" : "_blank",
          "href" : fullViewerUrl,
          "title": externalViewerProperties.title,
          "text" : externalViewerProperties.text
        });

        // Select the HTML element where the viewer will be embedded
        $( selector ).each( function () {

          // Get the selector DOM element
          var $thisSelector = $( this );

          // Add the credit text, viewer provider link, and link to full viewer
          // before the selector
          var $viewerMessage = $("<div/>",
            { "display": "block", "style": "padding-bottom: 1em;" }
          )
            .append($iiifLogo)
            .append($viewerProviderLogo)
            .append($viewerProvider)
            .append(". ")
            .append($externalViewerLink)
          $thisSelector.before($viewerMessage);

          // Add the iframe viewer before the selector
          $thisSelector.before($viewer);

        }); // end $( selector ).each( function () {

      }); // end $( snakview, iiifParent).each( function () {

    } // end if ( $("#" + iiifManifestUrlPropertyCode ).length ) {

  } // end function init

  $( function () {
    mw.hook( 'wikipage.content' ).add( init );
  } );

} ( mediaWiki, jQuery ) );