texinfo-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

branch master updated: * tp/tests/layout/list-of-tests (formatting_epub_


From: Gavin D. Smith
Subject: branch master updated: * tp/tests/layout/list-of-tests (formatting_epub_nodes): Do not set INFO_JS_DIR to avoid test result having to be updated every time one of the js files changes.
Date: Sun, 20 Nov 2022 11:35:49 -0500

This is an automated email from the git hooks/post-receive script.

gavin pushed a commit to branch master
in repository texinfo.

The following commit(s) were added to refs/heads/master by this push:
     new d51b32ce86 * tp/tests/layout/list-of-tests (formatting_epub_nodes): Do 
not set INFO_JS_DIR to avoid test result having to be updated every time one of 
the js files changes.
d51b32ce86 is described below

commit d51b32ce865df506900e6e731a1d7b9670971b15
Author: Gavin Smith <gavinsmith0123@gmail.com>
AuthorDate: Sun Nov 20 16:35:17 2022 +0000

    * tp/tests/layout/list-of-tests (formatting_epub_nodes):
    Do not set INFO_JS_DIR to avoid test result having to be
    updated every time one of the js files changes.
---
 ChangeLog                                          |    6 +
 tp/tests/layout/list-of-tests                      |    2 +-
 .../formatting_epub_package/EPUB/formatting.opf    |   19 +-
 .../formatting_epub_package/EPUB/js/info.css       |  255 ---
 .../formatting_epub_package/EPUB/js/info.js        | 2231 --------------------
 .../formatting_epub_package/EPUB/js/modernizr.js   |  767 -------
 .../EPUB/xhtml/chapter.xhtml                       |    6 +-
 .../EPUB/xhtml/chapter2.xhtml                      |    6 +-
 .../EPUB/xhtml/formatting.xhtml                    |    6 +-
 .../EPUB/xhtml/formatting_abt.xhtml                |    6 +-
 .../EPUB/xhtml/formatting_fot.xhtml                |    6 +-
 .../EPUB/xhtml/formatting_ovr.xhtml                |    6 +-
 .../EPUB/xhtml/formatting_toc.xhtml                |    6 +-
 .../EPUB/xhtml/js_licenses.xhtml                   |   17 -
 .../EPUB/xhtml/s_002d_002dect_002cion.xhtml        |    6 +-
 .../EPUB/xhtml/subsection.xhtml                    |    6 +-
 ...ion-_0060_0060simple_002ddouble_002d_002d.xhtml |    6 +-
 ...2d_002dfour_002d_002d_002d_002d_0027_0027.xhtml |    6 +-
 18 files changed, 36 insertions(+), 3327 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c58c076497..760266da0b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2022-11-20  Gavin Smith  <gavinsmith0123@gmail.com>
+
+       * tp/tests/layout/list-of-tests (formatting_epub_nodes):
+       Do not set INFO_JS_DIR to avoid test result having to be
+       updated every time one of the js files changes.
+
 2022-11-20  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/Convert/HTML.pm (output_internal_links): add subentries
diff --git a/tp/tests/layout/list-of-tests b/tp/tests/layout/list-of-tests
index 4308266eb3..e228292e30 100644
--- a/tp/tests/layout/list-of-tests
+++ b/tp/tests/layout/list-of-tests
@@ -43,7 +43,7 @@ formatting_inline_css formatting.texi -c 'INLINE_CSS_STYLE 1' 
-c DOCTYPE='<!DOCT
 formatting_fr_icons formatting.texi --document-language fr --init icons.init
 formatting_chm formatting.texi -c FORMAT_MENU=nomenu --init chm.pm
 formatting_epub formatting.texi --epub3 -c 'EPUB_CREATE_CONTAINER_FILE 0'
-formatting_epub_nodes formatting.texi --split node --init epub3.pm -c 
'EPUB_CREATE_CONTAINER_FILE 0' -c INFO_JS_DIR=js
+formatting_epub_nodes formatting.texi --split node --init epub3.pm -c 
'EPUB_CREATE_CONTAINER_FILE 0'
 formatting formatting.texi 
--internal-links=@OUT_DIR@internal_links_formatting.txt
 
 #lightweight_markups_mediawiki lightweight_markups.texi --init mediawiki.pm
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/formatting.opf
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/formatting.opf
index 075d3baed5..fbc56b25b1 100644
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/formatting.opf
+++ 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/formatting.opf
@@ -10,14 +10,13 @@
    </metadata>
    <manifest>
       <item id="nav" properties="nav" media-type="application/xhtml+xml" 
href="xhtml/nav_toc.xhtml"/>
-      <item id="unit1" media-type="application/xhtml+xml" 
href="xhtml/formatting.xhtml" properties="scripted"/>
-      <item id="unit2" media-type="application/xhtml+xml" 
href="xhtml/chapter.xhtml" properties="scripted"/>
-      <item id="unit3" media-type="application/xhtml+xml" 
href="xhtml/s_002d_002dect_002cion.xhtml" properties="scripted"/>
-      <item id="unit4" media-type="application/xhtml+xml" 
href="xhtml/subsection.xhtml" properties="scripted"/>
-      <item id="unit5" media-type="application/xhtml+xml" 
href="xhtml/subsubsection-_0060_0060simple_002ddouble_002d_002d.xhtml" 
properties="scripted"/>
-      <item id="unit6" media-type="application/xhtml+xml" 
href="xhtml/subsubsection-three_002d_002d_002dfour_002d_002d_002d_002d_0027_0027.xhtml"
 properties="scripted"/>
-      <item id="unit7" media-type="application/xhtml+xml" 
href="xhtml/chapter2.xhtml" properties="scripted"/>
-      <item id="jsweblabels" media-type="application/xhtml+xml" 
href="xhtml/js_licenses.xhtml"/>
+      <item id="unit1" media-type="application/xhtml+xml" 
href="xhtml/formatting.xhtml"/>
+      <item id="unit2" media-type="application/xhtml+xml" 
href="xhtml/chapter.xhtml"/>
+      <item id="unit3" media-type="application/xhtml+xml" 
href="xhtml/s_002d_002dect_002cion.xhtml"/>
+      <item id="unit4" media-type="application/xhtml+xml" 
href="xhtml/subsection.xhtml"/>
+      <item id="unit5" media-type="application/xhtml+xml" 
href="xhtml/subsubsection-_0060_0060simple_002ddouble_002d_002d.xhtml"/>
+      <item id="unit6" media-type="application/xhtml+xml" 
href="xhtml/subsubsection-three_002d_002d_002dfour_002d_002d_002d_002d_0027_0027.xhtml"/>
+      <item id="unit7" media-type="application/xhtml+xml" 
href="xhtml/chapter2.xhtml"/>
       <item id="image1" media-type="e--xt/image" 
href="images/11-f--ile.e--xt"/>
       <item id="image2" media-type="image/png" href="images/15-f--ile.png"/>
       <item id="image3" media-type="image/png" href="images/16-f--ile.png"/>
@@ -58,9 +57,6 @@
       <item id="image38" media-type="image/png" href="images/7-f--ile.png"/>
       <item id="image39" media-type="e--xt/image" 
href="images/8-f--ile.e--xt"/>
       <item id="image40" media-type="image/png" href="images/9-f--ile.png"/>
-      <item id="infojs1" media-type="text/css" href="js/info.css"/>
-      <item id="infojs2" media-type="text/javascript" href="js/info.js"/>
-      <item id="infojs3" media-type="text/javascript" href="js/modernizr.js"/>
    </manifest>
    <spine>
       <itemref idref="unit1"/>
@@ -70,6 +66,5 @@
       <itemref idref="unit5"/>
       <itemref idref="unit6"/>
       <itemref idref="unit7"/>
-      <itemref idref="jsweblabels" linear="no"/>
    </spine>
 </package>
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/js/info.css
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/js/info.css
deleted file mode 100644
index 14537b67ad..0000000000
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/js/info.css
+++ /dev/null
@@ -1,255 +0,0 @@
-/*-----------.
-| Sub pages  |
-`-----------*/
-
-body.in-iframe, div[node]#index {
-    padding: 0px 0.5em 0px 1em;
-}
-
-header > a {
-    width: 90%;
-    display: inline-block;
-}
-
-#sub-pages {
-    box-sizing: border-box;
-    left: 25%;     width: 75%;
-    height: auto;
-    top: 0pt;
-    bottom: 0pt;
-    position: absolute;
-}
-
-div[node] {
-    height: 100%;
-    overflow: auto;
-}
-body[show-sidebar="no"] div#sub-pages {
-    left: 0px;
-    width: 100%;
-}
-
-div[node][hidden] {
-    display: none;
-}
-
-/* Non-iframed main page */
-body.in-iframe {
-    margin: 0px;
-}
-
-div.toc-sidebar {
-    bottom: 2.8ex;
-}
-
-.toc-sidebar header {
-    display: flex;
-    align-items: flex-start;
-}
-
-.sidebar-hider span.hide-icon {
-    display: block;
-}
-.sidebar-hider span.hide-text {
-    display: block;
-    writing-mode: vertical-rl
-}
-
-.sidebar-hider {
-    display: inline;
-    padding: 2px;
-    vertical-align: top;
-    text-align: start;
-}
-.sidebar-hider span.hide-icon {
-    font-size: x-large;
-}
-
-/* Iframed sub pages */
-iframe.node {
-    width: 100%;
-    height: 100%;
-    border: none;
-    margin: 0px;
-    padding: 0px;
-}
-
-#sub-pages.blurred {
-    opacity: 0.2;
-}
-
-.highlight {
-    background: lightgrey;
-}
-
-/*--------------------------.
-| Lateral table of content  |
-`--------------------------*/
-
-#slider {
-    position: fixed;
-    top: 0em;
-    bottom: 0em;
-    height: 100%;
-    width: 25%;
-    margin: 0px;
-    padding: 0px;
-}
-
-#slider, body[show-sidebar="yes"] .sidebar-hider {
-    box-sizing: border-box;
-    left: 0em;
-}
-body[show-sidebar="yes"] .sidebar-hider {
-}
-body[show-sidebar="no"] #slider {
-    width: 0px; /* so mouse events don't get captured */
-}
-body[show-sidebar="no"] .sidebar-hider {
-    width: auto;
-    position: fixed;
-}
-
-body[show-sidebar="no"] div.toc, body[show-sidebar="no"] header > a {
-    display: none }
-
-div.toc-sidebar {
-    position: absolute;
-    top: 0px;
-    overflow: auto;
-}
-
-div.toc-sidebar header {
-    font-size: xx-large;
-}
-
-div.toc-sidebar div {
-    padding: 0.25em;
-    overflow: auto;
-}
-
-div.toc ul[toc-detail] {
-    display: none
-}
-
-div.toc ul, div toc nav {
-    margin: 0px;
-    padding: 0px;
-}
-
-div.toc ul ul {
-    margin-left: 1em;
-}
-
-div.toc a[toc-current] {
-    font-weight: bold
-}
-
-/*-------------.
-| Help screen  |
-`-------------*/
-
-table#keyboard-shortcuts {
-    margin: 20px;
-}
-
-table#keyboard-shortcuts td {
-    padding: 5px;
-}
-
-table#keyboard-shortcuts th {
-    text-align: left;
-}
-
-/* The Modal (background) hidden by default */
-.modal {
-    display: none;
-    position: fixed;
-    z-index: 1;
-    padding-top: 40px;
-    left: 25%;
-    top: 0;
-    bottom: 0px;
-    width: 75%;
-    background-color: #888; /* Fallback color */
-    background-color: rgba(0,0,0,0.5); /* Black w/ opacity */
-}
-
-/* Modal Content */
-.modal-content {
-    background-color: white;
-    margin: auto;
-    padding: 20px;
-    width: 80%;
-    max-height: 100%;
-    overflow-y: auto;
-}
-
-/*-------.
-| Icons  |
-`-------*/
-
-/* The Close Button */
-.close {
-    color: darkgrey;
-    float: right;
-    font-size: xx-large;
-}
-
-#icon-bar {
-    float: right;
-}
-
-.icon {
-    color: darkgrey;
-    font-size: x-large;
-}
-
-.icon:hover, .icon:focus, .close:hover, .close:focus {
-    color: black;
-    cursor: pointer;
-}
-
-/*--------.
-| popups  |
-`--------*/
-
-.text-input, .echo-area, .error {
-    background: lightgrey;
-    z-index: 10;
-    position: fixed;
-    right: 0;
-}
-
-.error .text-input {
-    top: 0;
-    right: 0;
-}
-
-.error {
-    background-color: orange;
-    padding: 5px;
-}
-
-.echo-area {
-    bottom: 0;
-}
-div.header { text-align: right }
-#slider {
-    background: #f0f0f0c0;
-}
-div.toc-sidebar nav, div.toc-sidebar header, .sidebar-hider {
-    background: #f0f0f0d0;
-}
-body[show-sidebar="yes"] .sidebar-hider {
-    border-width: thin;
-}
-body[show-sidebar="no"] .sidebar-hider {
-    border-width: thin;
-}
-@media (max-width: 60em) {
-    div#sub-pages { left: 0px; width: 100% }
-    body[show-sidebar="yes"] div#sub-pages { opacity: 0.4 }
-    body[show-sidebar="yes"] div#slider {width: 20em }
-    div.logo img { max-width: 80%; width: 2em; }
-}
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/js/info.js
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/js/info.js
deleted file mode 100644
index f5039928b4..0000000000
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/js/info.js
+++ /dev/null
@@ -1,2231 +0,0 @@
-/* info.js - Javascript UI for Texinfo manuals
-   Copyright (C) 2017-2019 Free Software Foundation, Inc.
-
-   This file is part of GNU Texinfo.
-
-   GNU Texinfo is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   GNU Texinfo is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with GNU Texinfo.  If not, see <http://www.gnu.org/licenses/>.  */
-
-(function (features, user_config) {
-  "use strict";
-
-  /*-------------------.
-  | Define constants.  |
-  `-------------------*/
-
-  /** To override those default parameters, define 'INFO_CONFIG' in the global
-      environment before loading this script.  */
-  var config = {
-    EXT: ".html",
-    INDEX_NAME: "index.html",
-    INDEX_ID: "index",
-    CONTENTS_ID: "SEC_Contents",
-    MAIN_ANCHORS: ["Top"],
-    WARNING_TIMEOUT: 3000,
-    SCREEN_MIN_WIDTH: 700,
-    LOCAL_HTML_PAGE_PATTERN: "^([^:/]*[.](html|htm|xhtml))?([#].*)?$",
-    SHOW_SIDEBAR_HTML: '<span class="hide-icon">&#x21db;</span>',
-    HIDE_SIDEBAR_HTML: '<span class="hide-icon">&#x21da;</span><span 
class="hide-text">Hide sidebar</span>',
-    SHOW_SIDEBAR_TOOLTIP: 'Show navigation sidebar',
-    HIDE_SIDEBAR_TOOLTIP: 'Hide navigation sidebar',
-
-    // hooks:
-    /** Define a function called after 'DOMContentLoaded' event in
-        the INDEX_NAME context.
-        @type {function (): void}*/
-    on_main_load: null,
-    /** Define a function called after 'DOMContentLoaded' event in
-        the iframe context.
-        @type {(function (): void)} */
-    on_iframe_load: null
-  };
-
-  /*-------------------.
-  | State Management.  |
-  `-------------------*/
-
-  /** A 'store' is an object managing the state of the application and having
-      a dispatch method which accepts actions as parameter.  This method is
-      the only way to update the state.
-      @typedef {function (Action): void} Action_consumer
-      @type {{dispatch: Action_consumer, state?: any, listeners?: any[]}}.  */
-  var store;
-
-  var section_names = [
-    'top', 'chapter', 'unnumbered', 'chapheading', 'appendix',
-    'section', 'unnumberedsec', 'heading', 'appendixsec',
-    'subsection', 'unnumberedsubsec', 'subheading', 'appendixsubsec',
-    'subsubsection', 'unnumberedsubsubsec', 'subsubheading',
-    'appendixsubsubsec' ];
-
-  /** Create a Store that calls its listeners at each state change.
-      @arg {function (Object, Action): Object} reducer
-      @arg {Object} state  */
-  function
-  Store (reducer, state)
-  {
-    this.listeners = [];
-    this.reducer = reducer;
-    this.state = state;
-  }
-
-  /** @arg {Action} action */
-  Store.prototype.dispatch = function dispatch (action) {
-    var new_state = this.reducer (this.state, action);
-    if (new_state !== this.state)
-      {
-        this.state = new_state;
-        if (window["INFO_DEBUG"])
-          console.log ("state: ", new_state);
-        this.listeners.forEach (function (listener) {
-          listener (new_state);
-        });
-      }
-  };
-
-  /** Build a store delegate that will forward its actions to a "real"
-      store that can be in a different browsing context.  */
-  function
-  Remote_store ()
-  {
-    /* The browsing context containing the real store.  */
-    this.delegate = window.parent;
-  }
-
-  /** Dispatch ACTION to the delegate browing context.  This method must be
-      used in conjunction of an event listener on "message" events in the
-      delegate browsing context which must forwards ACTION to an actual store.
-      @arg {Action} action */
-  Remote_store.prototype.dispatch = function dispatch (action) {
-    this.delegate.postMessage ({ message_kind: "action", action: action }, 
"*");
-  };
-
-  /** @typedef {{type: string, [x: string]: any}} Action - Payloads
-      of information meant to be treated by the store which can receive them
-      using the 'store.dispatch' method.  */
-
-  /* Place holder for action creators.  */
-  var actions = {
-    /** Return an action that makes LINKID the current page.
-        @arg {string} linkid - link identifier
-        @arg {string|false} [history] - method name that will be applied on
-        the 'window.history' object.  */
-    set_current_url: function (linkid, history, clicked = false) {
-      if (undef_or_null (history))
-        history = "pushState";
-      return { type: "current-url", url: linkid,
-               history: history, clicked: clicked };
-    },
-
-    /** Set current URL to the node corresponding to POINTER which is an
-        id refering to a linkid (such as "*TOP*" or "*END*"). */
-    set_current_url_pointer: function (pointer) {
-      return { type: "current-url", pointer: pointer, history: "pushState" };
-    },
-
-    /** @arg {string} dir */
-    navigate: function (dir) {
-      return { type: "navigate", direction: dir, history: "pushState" };
-    },
-
-    /** @arg {{[id: string]: string}} links */
-    cache_links: function (links) {
-      return { type: "cache-links", links: links };
-    },
-
-    /** @arg {NodeListOf<Element>} links */
-    cache_index_links: function (links) {
-      var dict = {};
-      for (var i = 0; i < links.length; i += 1)
-        {
-          var link = links[i];
-          dict[link.textContent] = href_hash (link_href (link));
-        }
-      return { type: "cache-index-links", links: dict };
-    },
-
-    /** Show or hide the help screen.  */
-    show_help: function () {
-      return { type: "help", visible: true };
-    },
-
-    /** Make the text input INPUT visible.  If INPUT is a falsy value then
-        hide current text input.
-        @arg {string} input */
-    show_text_input: function (input) {
-      return { type: "input", input: input };
-    },
-
-    /** Hide the current current text input.  */
-    hide_text_input: function () {
-      return { type: "input", input: null };
-    },
-
-    /** @arg {string} msg */
-    warn: function (msg) {
-      return { type: "warning", msg: msg };
-    },
-
-    window_title: function (title) {
-      return { type: "window-title", title: title };
-    },
-
-    /** Search EXP in the whole manual.
-        @arg {RegExp|string} exp*/
-    search: function (exp) {
-      var rgxp;
-      if (typeof exp === "object")
-        rgxp = exp;
-      else if (exp === "")
-        rgxp = null;
-      else
-        rgxp = new RegExp (exp, "i");
-
-      return { type: "search-init", regexp: rgxp, input: exp };
-    }
-  };
-
-  /** Update STATE based on the type of ACTION.  This update is purely
-      fonctional since STATE is not modified in place and a new state object
-      is returned instead.
-      @arg {Object} state
-      @arg {Action} action
-      @return {Object} a new state */
-  /* eslint-disable complexity */
-  /* A "big" switch has been preferred over splitting each case in a separate
-     function combined with a dictionary lookup.  */
-  function
-  updater (state, action)
-  {
-    var res = Object.assign ({}, state, { action: action });
-    var linkid;
-    switch (action.type)
-      {
-      case "cache-links":
-        {
-          var nodes = Object.assign ({}, state.loaded_nodes);
-          Object
-            .keys (action.links)
-            .forEach (function (key) {
-              if (typeof action.links[key] === "object")
-                nodes[key] = Object.assign ({}, nodes[key], action.links[key]);
-              else
-                nodes[key] = action.links[key];
-            });
-
-          return Object.assign (res, { loaded_nodes: nodes });
-        }
-      case "cache-index-links":
-        {
-          // Initially res.index is undefined, which is ignored.
-          res.index = Object.assign ({}, res.index, action.links);
-          return res;
-        }
-      case "section":
-        {
-          res.section_hash = action.section_hash;
-          return res;
-        }
-      case "current-url":
-        {
-          if (document.body.getAttribute("show-sidebar") == "yes"
-              && is_narrow_window ()
-              && action.clicked === "in-page")
-            return state;
-          linkid = (action.pointer) ?
-              state.loaded_nodes[action.pointer] : action.url;
-
-          res.current = linkid;
-          res.section_hash = null;
-          res.history = action.history;
-          res.text_input = null;
-          res.warning = null;
-          res.window_title = null;
-          res.help = false;
-          res.focus = false;
-          res.highlight = null;
-          res.loaded_nodes = Object.assign ({}, res.loaded_nodes);
-          res.loaded_nodes[linkid] = res.loaded_nodes[linkid] || {};
-          return res;
-        }
-      case "unfocus":
-        {
-          if (!res.focus)
-            return state;
-          else
-            {
-              res.help = false;
-              res.text_input = null;
-              res.focus = false;
-              return res;
-            }
-        }
-      case "help":
-        {
-          res.help = action.visible;
-          res.focus = true;
-          return res;
-        }
-      case "show-sidebar": // "yes" (show), "no" (hide) or "hide-if-narrow"
-        {
-          res.show_sidebar = action.show === "hide-if-narrow" && 
res.show_sidebar === "no" ? "no" : action.show;
-          return res;
-        }
-      case "navigate":
-        {
-          var current = state.current;
-          var link = linkid_split (state.current);
-
-          /* Handle inner 'config.INDEX_NAME' anchors specially.  */
-          if (link.pageid === config.INDEX_ID)
-            current = config.INDEX_ID;
-
-          var ids = state.loaded_nodes[current];
-          linkid = ids[action.direction];
-          if (!linkid)
-            {
-              // Look for sibling link in ToC.
-              // Needed for (say) @subsection without corresponding @node.
-              let toc_current =
-                document.querySelector ('#slider a[toc-current="yes"]');
-              if (toc_current)
-                {
-                  let item_current = toc_current.parentNode; // 'li' element
-                  let nlink = (action.direction === "next"
-                               ? item_current.nextElementSibling
-                               : action.direction === "prev"
-                               ? item_current.previousElementSibling
-                               : action.direction === "up"
-                               ? item_current.parentNode.parentNode
-                               : null);
-                  if (nlink)
-                    nlink = nlink.firstElementChild;
-                  if (nlink && nlink.matches("a"))
-                    {
-                      let href = link_href (nlink)
-                      if (href)
-                        linkid = href_hash (href) ;
-                    }
-                }
-            }
-          if (!linkid)
-            {
-              /* When CURRENT is in index but doesn't have the requested
-                 direction, ask its corresponding 'pageid'.  */
-              var is_index_ref =
-                Object.keys (state.index)
-                      .reduce (function (acc, val) {
-                        return acc || state.index[val] === current;
-                      }, false);
-              if (is_index_ref)
-                {
-                  ids = state.loaded_nodes[link.pageid];
-                  linkid = ids[action.direction];
-                }
-            }
-
-          if (!linkid)
-            return state;
-          else
-            {
-              res.current = linkid;
-              res.section_hash = null;
-              res.history = action.history;
-              res.text_input = null;
-              res.warning = null;
-              res.window_title = null;
-              res.help = false;
-              res.highlight = null;
-              res.focus = false;
-              res.loaded_nodes = Object.assign ({}, res.loaded_nodes);
-              res.loaded_nodes[action.url] = res.loaded_nodes[action.url] || 
{};
-              return res;
-            }
-        }
-      case "search-init":
-        {
-          res.search = {
-            regexp: action.regexp || state.search.regexp,
-            input: action.input || state.search.input,
-            status: "ready",
-            current_pageid: linkid_split (state.current).pageid,
-            found: false
-          };
-          res.focus = false;
-          res.help = false;
-          res.text_input = null;
-          res.warning = null;
-          return res;
-        }
-      case "search-query":
-        {
-          res.search = Object.assign ({}, state.search);
-          res.search.status = "searching";
-          return res;
-        }
-      case "search-result":
-        {
-          res.search = Object.assign ({}, state.search);
-          if (action.found)
-            {
-              res.search.status = "done";
-              res.search.found = true;
-              res.current = res.search.current_pageid;
-              res.section_hash = null;
-              res.history = "pushState";
-              res.highlight = res.search.regexp;
-            }
-          else
-            {
-              var fwd = forward_pageid (state, state.search.current_pageid);
-              if (fwd === null)
-                {
-                  res.search.status = "done";
-                  res.warning = "Search failed: \"" + res.search.input + "\"";
-                  res.highlight = null;
-                }
-              else
-                {
-                  res.search.current_pageid = fwd;
-                  res.search.status = "ready";
-                }
-            }
-          return res;
-        }
-      case "input":
-        {
-          var needs_update = (state.text_input && !action.input)
-              || (!state.text_input && action.input)
-              || (state.text_input && action.input
-                  && state.text_input !== action.input);
-
-          if (!needs_update)
-            return state;
-          else
-            {
-              res.focus = Boolean (action.input);
-              res.help = false;
-              res.text_input = action.input;
-              res.warning = null;
-              return res;
-            }
-        }
-      case "iframe-ready":
-        {
-          res.ready = Object.assign ({}, res.ready);
-          res.ready[action.id] = true;
-          return res;
-        }
-      case "echo":
-        {
-          res.echo = action.msg;
-          return res;
-        }
-      case "window-title":
-        {
-          res.window_title = action.title;
-          return res;
-        }
-      case "warning":
-        {
-          res.warning = action.msg;
-          if (action.msg !== null)
-            res.text_input = null;
-          return res;
-        }
-      default:
-        console.error ("no reducer for action type:", action.type);
-        return state;
-      }
-  }
-  /* eslint-enable complexity */
-
-  /*-----------------------.
-  | Context initializers.  |
-  `-----------------------*/
-
-  /** Initialize the index page of the manual which manages the state of the
-      application.  */
-  function
-  init_index_page ()
-  {
-    /*--------------------------.
-    | Component for help page.  |
-    `--------------------------*/
-
-    function
-    Help_page ()
-    {
-      this.id = "help-screen";
-      /* Create help div element.*/
-      var div = document.createElement ("div");
-      div.setAttribute ("hidden", "true");
-      div.classList.add ("modal");
-      div.innerHTML = "\
-<div class=\"modal-content\">\
-<span class=\"close\">&times;</span>\
-<h2>Keyboard Shortcuts</h2>\
-<table id=\"keyboard-shortcuts\">\
-  <tbody>\
-    <tr><th colspan=\"2\">Moving around</th></tr>\
-    <tr><td><code><b>n / p</b></code></td>\
-        <td>goto the next / previous section</td></tr>\
-    <tr><td><code><b>[ / ]</b></code></td>\
-        <td>goto the next / previous sibling</td></tr>\
-    <tr><td><code><b>&lt; / &gt;</b></code></td>\
-        <td>goto the first / last section</td></tr>\
-    <tr><td><code><b>t</b></code></td><td>goto the first section</td></tr>\
-    <tr><td><code><b>u</b></code></td>\
-        <td>go one level up (parent section)</td></tr>\
-    <tr><td><code><b>l / r</b></code></td>\
-        <td>go back / forward in history.</td></tr>\
-  </tbody>\
-  <tbody>\
-    <tr><th colspan=\"2\">Searching</th></tr>\
-    <tr><td><code><b>i</b></code></td><td>search in the index</td></tr>\
-    <tr><td><code><b>s</b></code></td>\
-        <td>global text search in the manual</td></tr>\
-    <tr><td><code><b>m</b></code></td>\
-        <td>search in current node menu</td></tr>\
-  </tbody>\
-  <tbody>\
-    <tr><th colspan=\"2\">Misc</th></tr>\
-    <tr><td><code><b>?</b></code></td><td>show this help screen</td></tr>\
-    <tr><td><code><b>Esc</b></code></td><td>hide this help screen</td></tr>\
-  </tbody>\
-</table>\
-</div>\
-";
-      var span = div.querySelector (".close");
-      div.addEventListener ("click", function (event) {
-        if (event.target === span || event.target === div)
-          store.dispatch ({ type: "unfocus" });
-      }, false);
-
-      this.element = div;
-    }
-
-    Help_page.prototype.render = function render (state) {
-      if (!state.help)
-        this.element.style.display = "none";
-      else
-        {
-          this.element.style.display = "block";
-          this.element.focus ();
-        }
-    };
-
-    /*---------------------------------.
-    | Components for menu navigation.  |
-    `---------------------------------*/
-
-    /** @arg {string} id */
-    function
-    Search_input (id)
-    {
-      this.id = id;
-      this.render = null;
-      this.prompt = document.createTextNode ("Text search" + ": ");
-
-      /* Create input div element.*/
-      var div = document.createElement ("div");
-      div.setAttribute ("hidden", "true");
-      div.appendChild (this.prompt);
-      this.element = div;
-
-      /* Create input element.*/
-      var input = document.createElement ("input");
-      input.setAttribute ("type", "search");
-      this.input = input;
-      this.element.appendChild (input);
-
-      /* Define a special key handler when 'this.input' is focused and
-         visible.*/
-      this.input.addEventListener ("keydown", (function (event) {
-        if (is_escape_key (event.key))
-          store.dispatch ({ type: "unfocus" });
-        else if (event.key === "Enter")
-          store.dispatch (actions.search (this.input.value));
-        event.stopPropagation ();
-      }).bind (this));
-    }
-
-    Search_input.prototype.show = function show () {
-      /* Display previous search. */
-      var search = store.state.search;
-      var input = search && (search.status === "done") && search.input;
-      if (input)
-        this.prompt.textContent = "Text search (default " + input + "): ";
-      this.element.removeAttribute ("hidden");
-      this.input.focus ();
-    };
-
-    Search_input.prototype.hide = function hide () {
-      this.element.setAttribute ("hidden", "true");
-      this.input.value = "";
-    };
-
-    /** @arg {string} id */
-    function
-    Text_input (id)
-    {
-      this.id = id;
-      this.data = null;
-      this.datalist = null;
-      this.render = null;
-
-      /* Create input div element.*/
-      var div = document.createElement ("div");
-      div.setAttribute ("hidden", "true");
-      div.appendChild (document.createTextNode (id + ": "));
-      this.element = div;
-
-      /* Create input element.*/
-      var input = document.createElement ("input");
-      input.setAttribute ("type", "search");
-      input.setAttribute ("list", id + "-data");
-      this.input = input;
-      this.element.appendChild (input);
-
-      /* Define a special key handler when 'this.input' is focused and
-         visible.*/
-      this.input.addEventListener ("keydown", (function (event) {
-        if (is_escape_key (event.key))
-          store.dispatch ({ type: "unfocus" });
-        else if (event.key === "Enter")
-          {
-            var linkid = this.data[this.input.value];
-            if (linkid)
-              {
-                hide_sidebar_if_narrow ();
-                store.dispatch (actions.set_current_url (linkid));
-              }
-          }
-        event.stopPropagation ();
-      }).bind (this));
-    }
-
-    /* Display a text input for searching through DATA.*/
-    Text_input.prototype.show = function show (data) {
-      if (!features || features.datalistelem)
-        {
-          var datalist = create_datalist (data);
-          datalist.setAttribute ("id", this.id + "-data");
-          this.data = data;
-          this.datalist = datalist;
-          this.element.appendChild (datalist);
-        }
-      this.element.removeAttribute ("hidden");
-      this.input.focus ();
-    };
-
-    Text_input.prototype.hide = function hide () {
-      this.element.setAttribute ("hidden", "true");
-      this.input.value = "";
-      if (this.datalist)
-        {
-          this.datalist.remove ();
-          this.datalist = null;
-        }
-    };
-
-    function
-    Minibuffer ()
-    {
-      /* Create global container.*/
-      var elem = document.createElement ("div");
-      elem.classList.add ("text-input");
-
-      var menu = new Text_input ("menu");
-      menu.render = function (state) {
-        if (state.text_input === "menu")
-        {
-          var current_menu = state.loaded_nodes[state.current].menu;
-          if (current_menu)
-            this.show (current_menu);
-          else
-            store.dispatch (actions.warn ("No menu in this node"));
-        }
-      };
-
-      var index = new Text_input ("index");
-      index.render = function (state) {
-        if (state.text_input === "index")
-        {
-          if (state.index)
-            this.show (state.index);
-          else
-            store.dispatch (actions.warn ("No index in this document"))
-        }
-      };
-
-      var search = new Search_input ("regexp-search");
-      search.render = function (state) {
-        if (state.text_input === "regexp-search")
-          this.show ();
-      };
-
-      elem.appendChild (menu.element);
-      elem.appendChild (index.element);
-      elem.appendChild (search.element);
-
-      /* Create a container for warning when no menu in current page.*/
-      var warn$ = document.createElement ("div");
-      warn$.setAttribute ("hidden", "true");
-      elem.appendChild (warn$);
-
-      this.element = elem;
-      this.menu = menu;
-      this.index = index;
-      this.search = search;
-      this.warn = warn$;
-      this.toid = null;
-    }
-
-    Minibuffer.prototype.render = function render (state) {
-      if (!state.warning)
-        {
-          this.warn.setAttribute ("hidden", "true");
-          this.toid = null;
-        }
-      else if (!this.toid)
-        {
-          console.warn (state.warning);
-          var toid = window.setTimeout (function () {
-            store.dispatch ({ type: "warning", msg: null });
-          }, config.WARNING_TIMEOUT);
-          this.warn.innerHTML = state.warning;
-          this.warn.removeAttribute ("hidden");
-          this.toid = toid;
-        }
-
-      if (!state.text_input || state.warning)
-        {
-          this.menu.hide ();
-          this.index.hide ();
-          this.search.hide ();
-        }
-      else
-        {
-          this.index.render (state);
-          this.menu.render (state);
-          this.search.render (state);
-        }
-    };
-
-    function
-    Echo_area ()
-    {
-      var elem = document.createElement ("div");
-      elem.classList.add ("echo-area");
-      elem.setAttribute ("hidden", "true");
-
-      this.element = elem;
-      this.toid = null;
-    }
-
-    Echo_area.prototype.render = function render (state) {
-      if (!state.echo)
-        {
-          this.element.setAttribute ("hidden", "true");
-          this.toid = null;
-        }
-      else if (!this.toid)
-        {
-          console.info (state.echo);
-          var toid = window.setTimeout (function () {
-            store.dispatch ({ type: "echo", msg: null });
-          }, config.WARNING_TIMEOUT);
-          this.element.innerHTML = state.echo;
-          this.element.removeAttribute ("hidden");
-          this.toid = toid;
-        }
-    };
-
-    /*----------------------------.
-    | Component for the sidebar.  |
-    `----------------------------*/
-
-    function
-    Sidebar (contents_node)
-    {
-      this.element = document.createElement ("div"); // FIXME unneeded?
-      this.element.setAttribute ("id", "slider");
-      var div = document.createElement ("div");
-      div.classList.add ("toc-sidebar");
-      var toc = document.querySelector ("#SEC_Contents");
-      toc.remove ();
-
-      // Like n.cloneNode, but also copy _href
-      function cloneNode(n)
-      {
-        let r = n.cloneNode(false);
-        for (let c = n.firstChild; c; c = c.nextSibling)
-          {
-            let d = cloneNode(c);
-            let h = c._href;
-            if (h)
-              d._href = h;
-            r.appendChild(d);
-          }
-        return r;
-      }
-      contents_node.appendChild(cloneNode(toc));
-
-      /* Remove table of contents header.  */
-      toc = toc.querySelector(".contents"); // skip ToC header
-
-      /* Move contents of <body> into a a fresh <div> to let the components
-         treat the index page like other iframe page.  */
-      var nav = document.createElement ("nav");
-      nav.classList.add ("contents");
-      for (var ch = toc.firstChild; ch; ch = toc.firstChild)
-        nav.appendChild (ch);
-
-      var div$ = document.createElement ("div");
-      div$.classList.add ("toc");
-      div$.appendChild (nav);
-      div.appendChild (div$);
-      this.element.appendChild (div);
-
-      let header = document.createElement ("header");
-      div$.parentElement.insertBefore (header, div$);
-      let hider = document.createElement ("button");
-      hider.classList.add ("sidebar-hider");
-      hider.innerHTML = config.HIDE_SIDEBAR_HTML;
-      this.show_sidebar_button = hider;
-      header.appendChild(hider);
-    }
-
-    /* Render 'sidebar' according to STATE which is a new state. */
-    Sidebar.prototype.render = function render (state) {
-      /* Update sidebar to highlight the title corresponding to
-         'state.current'.*/
-      let currently_showing = document.body.getAttribute("show-sidebar");
-      let show = state.show_sidebar;
-      if (show == "hide-if-narrow")
-        show = is_narrow_window() || currently_showing == "no" ? "no" : "yes";
-      if (show === undefined)
-        show = "yes";
-      if (show !== currently_showing)
-        {
-          document.body.setAttribute("show-sidebar", show);
-          this.show_sidebar_button.innerHTML = show == "yes" ? 
config.HIDE_SIDEBAR_HTML : config.SHOW_SIDEBAR_HTML;
-          let tooltip = show == "yes" ? config.HIDE_SIDEBAR_TOOLTIP : 
config.SHOW_SIDEBAR_TOOLTIP;
-          if (tooltip)
-            this.show_sidebar_button.setAttribute("title", tooltip);
-          else
-            this.show_sidebar_button.removeAttribute("title");
-        }
-      var msg = { message_kind: "update-sidebar", selected: state.current, 
section_hash: state.section_hash };
-      window.postMessage (msg, "*");
-    };
-
-    /*--------------------------.
-    | Component for the pages.  |
-    `--------------------------*/
-
-    /** @arg {HTMLDivElement} index_div */
-    function
-    Pages (index_div)
-    {
-      index_div.setAttribute ("id", config.INDEX_ID);
-      index_div.setAttribute ("node", config.INDEX_ID);
-      index_div.setAttribute ("hidden", "true");
-      this.element = document.createElement ("div");
-      this.element.setAttribute ("id", "sub-pages");
-      this.element.appendChild (index_div);
-      /** @type {string[]} Currently created divs.  */
-      this.ids = [config.INDEX_ID];
-      /** @type {string} */
-      this.prev_id = null;
-      /** @type {HTMLElement} */
-      this.prev_div = null;
-      this.prev_search = null;
-      this.main_title = document.title;
-    }
-
-    Pages.prototype.add_div = function add_div (pageid) {
-      var div = document.createElement ("div");
-      div.setAttribute ("id", pageid);
-      div.setAttribute ("node", pageid);
-      div.setAttribute ("hidden", "true");
-      this.ids.push (pageid);
-      this.element.appendChild (div);
-      if (linkid_contains_index (pageid))
-        load_page (pageid);
-      return div;
-    };
-
-    Pages.prototype.render = function render (state) {
-      var that = this;
-
-      /* Create div elements for pages corresponding to newly added
-         linkids from 'state.loaded_nodes'.*/
-      Object.keys (state.loaded_nodes)
-            .map (function (id) { return id.replace (/\..*$/, ""); })
-            .filter (function (id) { return !that.ids.includes (id); })
-            .reduce (function (acc, id) {
-              return ((acc.includes (id)) ? acc : acc.concat ([id]));
-            }, [])
-            .forEach (function (id) { return that.add_div (id); });
-
-      /* Blur pages if help screen is on.  */
-      this.element.classList[(state.help) ? "add" : "remove"] ("blurred");
-      let div = this.prev_div;
-      if (state.current !== this.prev_id)
-        {
-          if (this.prev_id)
-            {
-              this.prev_div.setAttribute ("hidden", "true");
-              /* Remove previous highlights.  */
-              var old = linkid_split (this.prev_id);
-              var msg = { message_kind: "highlight", regexp: null };
-              post_message (old.pageid, msg);
-            }
-          div = resolve_page (state.current, true);
-          update_history (state.current, state.history);
-          this.prev_id = state.current;
-          this.prev_div = div;
-        }
-        if (state.action.type === "window-title") {
-            div.setAttribute("title", state.action.title);
-        }
-        let title = div.getAttribute("title") || this.main_title;
-        if (title && document.title !== title)
-            document.title = title;
-
-      if (state.search
-          && (this.prev_search !== state.search)
-          && state.search.status === "ready")
-        {
-          this.prev_search = state.search;
-          if (state.search.current_pageid === config.INDEX_ID)
-            {
-              window.setTimeout (function () {
-                store.dispatch ({ type: "search-query" });
-                var res = search (document.getElementById (config.INDEX_ID),
-                                  state.search.regexp);
-                store.dispatch ({ type: "search-result", found: res });
-              }, 0);
-            }
-          else
-            {
-              window.setTimeout (function () {
-                store.dispatch ({ type: "search-query" });
-                var msg = {
-                  message_kind: "search",
-                  regexp: state.search.regexp,
-                  id: state.search.current_pageid
-                };
-                post_message (state.search.current_pageid, msg);
-              }, 0);
-            }
-        }
-
-      /* Update highlight of current page.  */
-      if (!state.highlight)
-        {
-          if (state.current === config.INDEX_ID)
-            remove_highlight (document.getElementById (config.INDEX_ID));
-          else
-            {
-              var link = linkid_split (state.current);
-              var msg$ = { message_kind: "highlight", regexp: null };
-              post_message (link.pageid, msg$);
-            }
-        }
-
-      /* Scroll to highlighted search result. */
-      if (state.search
-          && (this.prev_search !== state.search)
-          && state.search.status === "done"
-          && state.search.found === true)
-        {
-          var link$ = linkid_split (state.current);
-          var msg$$ = { message_kind: "scroll-to", hash: "#search-result" };
-          post_message (link$.pageid, msg$$);
-          this.prev_search = state.search;
-        }
-    };
-
-    /*--------------.
-    | Utilitaries.  |
-    `--------------*/
-
-    /** Load PAGEID.
-        @arg {string} pageid */
-    function
-    load_page (pageid)
-    {
-      var div = resolve_page (pageid, false);
-      /* Making the iframe visible triggers the load of the iframe DOM.  */
-      if (div.hasAttribute ("hidden"))
-        {
-          div.removeAttribute ("hidden");
-          div.setAttribute ("hidden", "true");
-        }
-    }
-
-    /** Return the div element that correspond to LINKID.  If VISIBLE is true
-        then display the div and position the corresponding iframe to the
-        anchor specified by LINKID.
-        @arg {string} linkid - link identifier
-        @arg {boolean} [visible]
-        @return {HTMLElement} the div element.  */
-    function
-    resolve_page (linkid, visible)
-    {
-      var msg;
-      var link = linkid_split (linkid);
-      var pageid = link.pageid;
-      var div = document.getElementById (link.pageid);
-      if (!div)
-        {
-          msg = "no iframe container correspond to identifier: " + pageid;
-          throw new ReferenceError (msg);
-        }
-
-      /* Create iframe if necessary unless the div is refering to the Index
-         or Contents page.  */
-      if (pageid === config.INDEX_ID || pageid === config.CONTENTS_ID)
-        {
-          div.removeAttribute ("hidden");
-          /* Unlike iframes, Elements are unlikely to be scrollable (CSSOM
-             Scroll-behavior), so choose an arbitrary element inside "index"
-             div and at the top of it.  */
-          document.getElementById ("icon-bar").scrollIntoView ();
-        }
-      else
-        {
-          var iframe = div.querySelector ("iframe");
-          if (!iframe)
-            {
-              iframe = document.createElement ("iframe");
-              iframe.classList.add ("node");
-              iframe.setAttribute ("src", linkid_to_url (pageid));
-              div.appendChild (iframe);
-              iframe.addEventListener ("load", function () {
-                store.dispatch ({ type: "iframe-ready", id: pageid });
-              }, false);
-            }
-          if (visible)
-            {
-              div.removeAttribute ("hidden");
-              msg = { message_kind: "scroll-to", hash: link.hash };
-              post_message (pageid, msg);
-            }
-        }
-
-      return div;
-    }
-
-    /** Create a datalist element containing option elements corresponding
-        to the keys in MENU.  */
-    function
-    create_datalist (menu)
-    {
-      var datalist = document.createElement ("datalist");
-      Object.keys (menu)
-            .sort ()
-            .forEach (function (title) {
-              var opt = document.createElement ("option");
-              opt.setAttribute ("value", title);
-              datalist.appendChild (opt);
-            });
-      return datalist;
-    }
-
-    /** Mutate the history of page navigation.  Store LINKID in history
-        state, The actual way to store LINKID depends on HISTORY_MODE.
-        @arg {string} linkid
-        @arg {string} history_mode */
-    function
-    update_history (linkid, history_mode)
-    {
-      var method = window.history[history_mode];
-      if (method)
-        {
-          /* Pretend that the current page is the one corresponding to the
-             LINKID iframe.  Handle errors since changing the visible file
-             name can fail on some browsers with the "file:" protocol.  */
-          var visible_url =
-            dirname (window.location.pathname) + linkid_to_url (linkid);
-          try
-            {
-              method.call (window.history, linkid, null, visible_url);
-            }
-          catch (err)
-            {
-              /* Fallback to changing only the hash part which is safer.  */
-              visible_url = window.location.pathname;
-              if (linkid !== config.INDEX_ID)
-                visible_url += ("#" + linkid);
-              method.call (window.history, linkid, null, visible_url);
-            }
-        }
-    }
-
-    /** Send MSG to the browsing context corresponding to PAGEID.  This is a
-        wrapper around 'Window.postMessage' which ensures that MSG is sent
-        after PAGEID is loaded.
-        @arg {string} pageid
-        @arg {any} msg */
-    function
-    post_message (pageid, msg)
-    {
-      if (pageid === config.INDEX_ID || pageid === config.CONTENTS_ID)
-        window.postMessage (msg, "*");
-      else
-        {
-          load_page (pageid);
-          var iframe = document.getElementById (pageid)
-                               .querySelector ("iframe");
-          /* Semantically this would be better to use "promises" however
-             they are not available in IE.  */
-          if (store.state.ready[pageid])
-            iframe.contentWindow.postMessage (msg, "*");
-          else
-            {
-              iframe.addEventListener ("load", function handler () {
-                this.contentWindow.postMessage (msg, "*");
-                this.removeEventListener ("load", handler, false);
-              }, false);
-            }
-        }
-    }
-
-    /*--------------------------------------------
-    | Event handlers for the top-level context.  |
-    `-------------------------------------------*/
-
-    /* Initialize the top level 'config.INDEX_NAME' DOM.  */
-    function
-    on_load ()
-    {
-      fix_links (document.links);
-      add_icons ();
-      document.body.classList.add ("mainbar");
-
-      /* Move contents of <body> into a a fresh <div> to let the components
-         treat the index page like other iframe page.  */
-      var index_div = document.createElement ("div");
-      for (var ch = document.body.firstChild; ch; ch = 
document.body.firstChild)
-        index_div.appendChild (ch);
-
-      /* Aggregation of all the sub-components.  */
-      var components = {
-        element: document.body,
-        components: [],
-
-        add: function add (component) {
-          this.components.push (component);
-          this.element.appendChild (component.element);
-        },
-
-        render: function render (state) {
-          this.components
-              .forEach (function (cmpt) { cmpt.render (state); });
-
-          /* Ensure that focus is on the current node unless some component is
-             focused.  */
-          if (!state.focus)
-            {
-              var link = linkid_split (state.current);
-              var elem = document.getElementById (link.pageid);
-              if (link.pageid !== config.INDEX_ID && link.pageid !== 
config.CONTENTS_ID)
-                elem.querySelector ("iframe").focus ();
-              else
-                {
-                  /* Move the focus to top DOM.  */
-                  document.documentElement.focus ();
-                  /* Allow the spacebar scroll in the main page to work.  */
-                  elem.focus ();
-                }
-            }
-        }
-      };
-      var pages = new Pages (index_div);
-      components.add (pages);
-      var contents_node = pages.add_div(config.CONTENTS_ID);
-      components.add (new Sidebar (contents_node));
-      components.add (new Help_page ());
-      components.add (new Minibuffer ());
-      components.add (new Echo_area ());
-      store.listeners.push (components.render.bind (components));
-
-      if (window.location.hash)
-        {
-          var linkid = normalize_hash (window.location.hash);
-          store.dispatch (actions.set_current_url (linkid, "replaceState"));
-        }
-
-      /* Retrieve NEXT link and local menu.  */
-      var links = {};
-      links[config.INDEX_ID] = navigation_links (document);
-      store.dispatch (actions.cache_links (links));
-      store.dispatch ({ type: "iframe-ready", id: config.INDEX_ID });
-      store.dispatch ({
-        type: "echo",
-        msg: "Welcome to Texinfo documentation viewer 6.1, type '?' for help."
-      });
-
-      /* Call user hook.  */
-      if (config.on_main_load)
-        config.on_main_load ();
-    }
-
-    /* Handle messages received via the Message API.
-       @arg {MessageEvent} event */
-    function
-    on_message (event)
-    {
-      var data = event.data;
-      if (data.message_kind === "action")
-        {
-          /* Follow up actions to the store.  */
-          store.dispatch (data.action);
-        }
-    }
-
-    /* Event handler for 'popstate' events.  */
-    function
-    on_popstate (event)
-    {
-      /* When EVENT.STATE is 'null' it means that the user has manually
-         changed the hash part of the URL bar.  */
-      var linkid = (event.state === null) ?
-        normalize_hash (window.location.hash) : event.state;
-      store.dispatch (actions.set_current_url (linkid, false));
-    }
-
-    return {
-      on_load: on_load,
-      on_message: on_message,
-      on_popstate: on_popstate
-    };
-  }
-
-  /** Initialize the iframe which contains the lateral table of content.  */
-  function
-  init_sidebar ()
-  {
-    /* Keep children but remove grandchildren (Exception: don't remove
-       anything on the current page; however, that's not a problem in the Kawa
-       manual).  */
-    function
-    hide_grand_child_nodes (ul, excluded)
-    {
-      var lis = ul.children;
-      for (var i = 0; i < lis.length; i += 1)
-        {
-          if (lis[i] === excluded)
-            continue;
-          var first = lis[i].firstElementChild;
-          if (first && first.matches ("ul"))
-            hide_grand_child_nodes (first);
-          else if (first && first.matches ("a"))
-            {
-              var ul$ = first && first.nextElementSibling;
-              if (ul$)
-                ul$.setAttribute ("toc-detail", "yes");
-            }
-        }
-    }
-
-    /** Make the parent of ELEMS visible.
-        @arg {HTMLElement} elem */
-    function
-    mark_parent_elements (elem)
-    {
-      if (elem && elem.parentElement && elem.parentElement.parentElement)
-        {
-          var pparent = elem.parentElement.parentElement;
-          for (var sib = pparent.firstElementChild; sib;
-               sib = sib.nextElementSibling)
-            {
-              if (sib !== elem.parentElement
-                  && sib.firstElementChild
-                  && sib.firstElementChild.nextElementSibling)
-                {
-                  sib.firstElementChild
-                     .nextElementSibling
-                     .setAttribute ("toc-detail", "yes");
-                }
-            }
-        }
-    }
-
-    /** Scan ToC entries to see which should be hidden.
-        @arg {HTMLElement} elem
-        @arg {string} linkid */
-    function
-    scan_toc (elem, linkid, section_hash = null)
-    {
-      /** @type {Element} */
-      var res;
-      if (section_hash)
-        {
-          let dot = linkid.lastIndexOf('.');
-          if (dot >= 0)
-            linkid = linkid.substring(0, dot+1) + section_hash;
-        }
-      var url = with_sidebar_query (linkid_to_url (linkid));
-
-      /** Set CURRENT to the node corresponding to URL linkid.
-          @arg {Element} elem */
-      function
-      find_current (elem)
-      {
-        if (elem.localName === "a" && link_href(elem) == url)
-          {
-            elem.setAttribute ("toc-current", "yes");
-            var sib = elem.nextElementSibling;
-            if (sib && sib.matches ("ul"))
-              hide_grand_child_nodes (sib);
-            res = elem;
-          }
-      }
-
-      var ul = elem.querySelector ("ul");
-      if (linkid === config.INDEX_ID || linkid === config.CONTENTS_ID)
-        {
-          hide_grand_child_nodes (ul);
-          res = document.getElementById(linkid);
-        }
-      else
-        {
-          depth_first_walk (ul, find_current, Node.ELEMENT_NODE);
-          /* Mark every parent node.  */
-          var current = res;
-          while (current && current !== ul)
-            {
-              mark_parent_elements (current);
-              /* XXX: Special case for manuals with '@part' commands.  */
-              if (current.parentElement === ul)
-                hide_grand_child_nodes (ul, current);
-              current = current.parentElement;
-            }
-        }
-      return res;
-    }
-
-    /* Build the global dictionary containing navigation links from NAV.  NAV
-       must be an 'ul' DOM element containing the table of content of the
-       manual.  */
-    function
-    create_link_dict (nav)
-    {
-      var prev_id = config.INDEX_ID;
-      var links = {};
-
-      function
-      add_link (elem)
-      {
-        let href;
-          if (elem.matches ("a") && (href = link_href(elem)))
-          {
-            var id = href_hash (href);
-            links[prev_id] =
-              Object.assign ({}, links[prev_id], { forward: id });
-            links[id] = Object.assign ({}, links[id], { backward: prev_id });
-            prev_id = id;
-          }
-      }
-
-      depth_first_walk (nav, add_link, Node.ELEMENT_NODE);
-      /* Add a reference to the first and last node of the manual.  */
-      links["*TOP*"] = config.INDEX_ID;
-      links["*END*"] = prev_id;
-      return links;
-    }
-
-    /* Add a link from the sidebar to the main index file.  ELEM is the first
-       sibling of the newly created header.  */
-    function
-    add_header (elem)
-    {
-      var h1 = document.querySelector ("h1.settitle");
-      if (h1)
-        {
-          var a = document.createElement ("a");
-          a.setAttribute ("href", config.INDEX_NAME);
-          a.setAttribute ("id", config.INDEX_ID);
-
-          let header = elem.previousSibling;
-          header.appendChild (a);
-          if (window.sidebarLinkAppendContents)
-            window.sidebarLinkAppendContents(a, h1.textContent);
-          else
-            {
-              var div = document.createElement ("div");
-              a.appendChild (div);
-              var span = document.createElement ("span");
-              span.textContent = h1.textContent;
-              div.appendChild (span);
-            }
-        }
-    }
-
-    /*------------------------------------------
-    | Event handlers for the sidebar context.  |
-    `-----------------------------------------*/
-
-    /* Initialize TOC_FILENAME which must be loaded in the context of an
-       iframe.  */
-    function
-    on_load ()
-    {
-      var toc_div = document.getElementById ("slider");
-      add_header (toc_div.querySelector (".toc"));
-
-      /* Specify the base URL to use for all relative URLs.  */
-      /* FIXME: Add base also for sub-pages.  */
-      var base = document.createElement ("base");
-      base.setAttribute ("href",
-                         window.location.href.replace (/[/][^/]*$/, "/"));
-      document.head.appendChild (base);
-
-      scan_toc (toc_div, config.INDEX_NAME);
-
-      /* Get 'backward' and 'forward' link attributes.  */
-      var dict = create_link_dict (toc_div.querySelector ("nav.contents ul"));
-      store.dispatch (actions.cache_links (dict));
-    }
-
-    /* Handle messages received via the Message API.  */
-    function
-    on_message (event)
-    {
-      var data = event.data;
-      if (data.message_kind === "update-sidebar")
-        {
-          var toc_div = document.getElementById ("slider");
-
-          /* Reset previous calls to 'scan_toc'.  */
-          depth_first_walk (toc_div, function clear_toc_styles (elem) {
-            elem.removeAttribute ("toc-detail");
-            elem.removeAttribute ("toc-current");
-          }, Node.ELEMENT_NODE);
-
-          /* Remove the hash part for the main page.  */
-          var pageid = linkid_split (data.selected).pageid;
-          var selected = (pageid === config.INDEX_ID) ? pageid : data.selected;
-          /* Highlight the current LINKID in the table of content.  */
-          var elem = scan_toc (toc_div, selected, data.section_hash);
-          if (elem)
-            elem.scrollIntoView (true);
-        }
-    }
-
-    return {
-      on_load: on_load,
-      on_message: on_message
-    };
-  }
-
-  /** Initialize iframes which contain pages of the manual.  */
-  function
-  init_iframe ()
-  {
-    /* Initialize the DOM for generic pages loaded in the context of an
-       iframe.  */
-    function
-    on_load ()
-    {
-      document.body.classList.add ("in-iframe");
-      fix_links (document.links);
-      var links = {};
-      var linkid = basename (window.location.pathname, /[.]x?html$/);
-      links[linkid] = navigation_links (document);
-      store.dispatch (actions.cache_links (links));
-      if (document.title)
-         store.dispatch (actions.window_title (document.title));
-
-      if (linkid_contains_index (linkid))
-        {
-          /* Scan links that should be added to the index.  */
-          var index_links = document.querySelectorAll
-            ("td.printindex-index-entry a");
-          store.dispatch (actions.cache_index_links (index_links));
-        }
-
-      add_icons ();
-
-      /* Call user hook.  */
-      if (config.on_iframe_load)
-        config.on_iframe_load ();
-    }
-
-    /* Handle messages received via the Message API.  */
-    function
-    on_message (event)
-    {
-      var data = event.data;
-      if (data.message_kind === "highlight")
-        remove_highlight (document.body);
-      else if (data.message_kind === "search")
-        {
-          var found = search (document.body, data.regexp);
-          store.dispatch ({ type: "search-result", found: found });
-        }
-      else if (data.message_kind === "scroll-to")
-        {
-          /* Scroll to the anchor corresponding to HASH.  */
-          if (data.hash)
-            {
-              let elem = document.getElementById(data.hash.substring(1));
-              // Check if hash reference is to a sectioing element.  
-              // If not we need to find the outer sectioning element,
-              // so we can update the sidebar's ToC correctly.
-              if (elem)
-                {
-                  let p = elem;
-                  let section = null;
-                  let id = null;
-                  for (let p = elem;
-                       section === null && p instanceof Element;
-                        p = p.parentNode)
-                    {
-                      let sid = p.getAttribute("id");
-                      if (sid == null)
-                        continue;
-                      let cl = p.classList;
-                      for (let i = cl.length; --i >= 0; )
-                        {
-                          if (section_names.indexOf(cl.item(i)) >= 0)
-                            {
-                              section = p;
-                              id = sid;
-                              break;
-                            }
-                        }
-                    }
-                    if (section && section !== elem)
-                      {
-                        // Send section id to sidebar so it can properly 
update.
-                        store.dispatch({ type: "section", hash: data.hash, 
section_hash: id } );
-                      }
-                }
-                window.location.replace (data.hash);
-            }
-          else
-            window.scroll (0, 0);
-        }
-    }
-
-    return {
-      on_load: on_load,
-      on_message: on_message
-    };
-  }
-
-  /*-------------------------
-  | Common event handlers.  |
-  `------------------------*/
-
-  /** Handle click events.  */
-  function
-  on_click (event)
-  {
-    let in_sidebar = event.target.matches ("#slider *");
-    for (var target = event.target; target !== null; target = 
target.parentNode)
-      {
-        if (! (target instanceof Element))
-          continue;
-        if (target.matches ("a"))
-          {
-            var href = link_href(target);
-            if (href && maybe_pageref_url_p (href)
-                  && !external_manual_url_p (href))
-              {
-                var linkid = href_hash (href) || config.INDEX_ID;
-                if (linkid === "index.SEC_Contents")
-                    linkid = config.CONTENTS_ID;
-                store.dispatch (actions.set_current_url (linkid, null,
-                                                         in_sidebar ? 
"in-sidebar" : "in-page"));
-                event.preventDefault ();
-                event.stopPropagation ();
-                break;
-              }
-          }
-        if (target.matches (".sidebar-hider"))
-          {
-              let body = document.body;
-              let show = body.getAttribute("show-sidebar");
-              show_sidebar (show==="no");
-              return;
-          }
-      }
-    if (! in_sidebar)
-      hide_sidebar_if_narrow ();
-  }
-
-  // Only valid when showing sidebar.
-  function is_narrow_window ()
-  {
-    return document.body.firstChild.offsetLeft == 0;
-  }
-
-  function show_sidebar (show)
-  {
-    store.dispatch({ type: "show-sidebar", show: show ? "yes" : "no" });
-  }
-
-  function hide_sidebar_if_narrow ()
-  {
-    store.dispatch({ type: "show-sidebar", show: "hide-if-narrow" });
-  }
-
-  /** Handle unload events.  */
-  function
-  on_unload ()
-  {
-    /* Cross origin requests are not supported in file protocol.  */
-    if (window.location.protocol !== "file:")
-    {
-      var request = new XMLHttpRequest ();
-      request.open ("GET", "(WINDOW-CLOSED)");
-      request.send (null);
-    }
-  }
-
-  /** Handle Keyboard 'keydown' events.
-      @arg {KeyboardEvent} event */
-  function
-  on_keydown (event)
-  {
-    if (is_escape_key (event.key))
-      store.dispatch ({ type: "unfocus" });
-    else
-      {
-        var val = on_keydown.dict[event.key];
-        if (val)
-          {
-            if (typeof val === "function")
-              val ();
-            else
-              store.dispatch (val);
-            event.preventDefault();
-          }
-      }
-  }
-
-  /* Associate an Event 'key' property to an action or a thunk.  */
-  on_keydown.dict = {
-    i: actions.show_text_input ("index"),
-    l: window.history.back.bind (window.history),
-    m: actions.show_text_input ("menu"),
-    n: actions.navigate ("next"),
-    p: actions.navigate ("prev"),
-    r: window.history.forward.bind (window.history),
-    s: actions.show_text_input ("regexp-search"),
-    t: actions.set_current_url_pointer ("*TOP*"),
-    u: actions.navigate ("up"),
-    "]": actions.navigate ("forward"),
-    "[": actions.navigate ("backward"),
-    "<": actions.set_current_url_pointer ("*TOP*"),
-    ">": actions.set_current_url_pointer ("*END*"),
-    "?": actions.show_help ()
-  };
-
-  /** Some standard methods used in this script might not be implemented by
-      the current browser.  If that is the case then augment the prototypes
-      appropriately.  */
-  function
-  register_polyfills ()
-  {
-    function
-    includes (search, start)
-    {
-      start = start || 0;
-      return ((start + search.length) <= this.length)
-        && (this.indexOf (search, start) !== -1);
-    }
-
-    /* eslint-disable no-extend-native */
-    if (!Array.prototype.includes)
-      Array.prototype.includes = includes;
-
-    if (!String.prototype.includes)
-      String.prototype.includes = includes;
-
-    if (!String.prototype.endsWith)
-      {
-        String.prototype.endsWith = function endsWith (search, position) {
-          var subject_string = this.toString ();
-          if (typeof position !== "number"
-              || !isFinite (position)
-              || Math.floor (position) !== position
-              || position > subject_string.length)
-            position = subject_string.length;
-
-          position -= search.length;
-          var last_index = subject_string.lastIndexOf (search, position);
-          return last_index !== -1 && last_index === position;
-        };
-      }
-
-    if (!Element.prototype.matches)
-      {
-        Element.prototype.matches = Element.prototype["matchesSelector"]
-          || Element.prototype["mozMatchesSelector"]
-          || Element.prototype["mozMatchesSelector"]
-          || Element.prototype["msMatchesSelector"]
-          || Element.prototype["webkitMatchesSelector"]
-          || function element_matches (str) {
-            var document = (this.document || this.ownerDocument);
-            var matches = document.querySelectorAll (str);
-            var i = matches.length;
-            while ((i -= 1) >= 0 && matches.item (i) !== this);
-            return i > -1;
-          };
-      }
-
-    if (typeof Object.assign != "function")
-      {
-        Object.assign = function assign (target) {
-          if (undef_or_null (target))
-            throw new TypeError ("Cannot convert undefined or null to object");
-
-          var to = Object (target);
-          for (var index = 1; index < arguments.length; index += 1)
-            {
-              var next_source = arguments[index];
-              if (undef_or_null (next_source))
-                continue;
-              for (var key in next_source)
-                {
-                  /* Avoid bugs when hasOwnProperty is shadowed.  */
-                  if (Object.prototype.hasOwnProperty.call (next_source, key))
-                    to[key] = next_source[key];
-                }
-            }
-          return to;
-        };
-      }
-
-    (function (protos) {
-      protos.forEach (function (proto) {
-        if (!proto.hasOwnProperty ("remove"))
-          {
-            Object.defineProperty (proto, "remove", {
-              configurable: true,
-              enumerable: true,
-              writable: true,
-              value: function value () {
-                this.parentNode.removeChild (this);
-              }
-            });
-          }
-      });
-    } ([Element.prototype, CharacterData.prototype, DocumentType.prototype]));
-    /* eslint-enable no-extend-native */
-  }
-
-  /*---------------------.
-  | Common utilitaries.  |
-  `---------------------*/
-
-  /** Check portably if KEY correspond to "Escape" key value.
-      @arg {string} key */
-  function
-  is_escape_key (key)
-  {
-    /* In Internet Explorer 9 and Firefox 36 and earlier, the Esc key
-       returns "Esc" instead of "Escape".  */
-    return key === "Escape" || key === "Esc";
-  }
-
-  /** Check if OBJ is equal to 'undefined' or 'null'.  */
-  function
-  undef_or_null (obj)
-  {
-    return (obj === null || typeof obj === "undefined");
-  }
-
-  /** Return a relative URL corresponding to HREF, which refers to an anchor
-      of 'config.INDEX_NAME'.  HREF must be a USVString representing an
-      absolute or relative URL.  For example "foo/bar.html" will return
-      "config.INDEX_NAME#bar".
-
-      @arg {string} href.*/
-  function
-  with_sidebar_query (href)
-  {
-    if (basename (href) === config.INDEX_NAME)
-      return config.INDEX_NAME;
-    else
-      {
-        /* XXX: Do not use the URL API for IE portability.  */
-        var url = with_sidebar_query.url;
-        url.setAttribute ("href", href);
-        var new_hash = "#" + basename (url.pathname, /[.]x?html/);
-        /* XXX: 'new_hash !== url.hash' is a workaround to work with links
-           produced by makeinfo which link to an anchor element in a page
-           instead of directly to the page. */
-        if (url.hash && new_hash !== url.hash)
-          new_hash += ("." + url.hash.slice (1));
-        return config.INDEX_NAME + new_hash;
-      }
-  }
-
-  /* Use the same DOM element for every function call.  */
-  with_sidebar_query.url = document.createElement ("a");
-
-  /** Modify LINKS to handle the iframe based navigation properly.  Relative
-      links will be opened inside the corresponding iframe and absolute links
-      will be opened in a new tab.  If ID is true then define an "id"
-      attribute with a linkid value for relative links.
-
-      @typedef {HTMLAnchorElement|HTMLAreaElement} Links
-      @arg {Links[]|HTMLCollectionOf<Links>} links
-      @arg {boolean} [id]
-      @return void  */
-  function
-  fix_links (links, id)
-  {
-    for (var i = 0; i < links.length; i += 1)
-      {
-        var link = links[i];
-        var href = link_href(link);
-        if (!href)
-          continue;
-        else if (external_manual_url_p (href))
-          link.setAttribute ("target", "_top");
-        else if (! maybe_pageref_url_p (href))
-          link.setAttribute ("target", "_blank");
-        else
-          {
-            var href$ = with_sidebar_query (href);
-            if (href !== href$)
-              {
-                let protocol = location.protocol;
-                if (protocol == "https:" || protocol == "http:")
-                  link._href = href$;
-                else
-                  link.setAttribute ("href", href$);
-              }
-            if (id)
-              {
-                var linkid = (href$ === config.INDEX_NAME) ?
-                    config.INDEX_ID : href_hash (href$);
-                link.setAttribute ("id", linkid);
-              }
-          }
-      }
-  }
-
-  /** Convert HASH which is something that can be found 'Location.hash' to a
-      "linkid" which can be handled in our model.
-      @arg {string} hash
-      @return {string} linkid */
-  function
-  normalize_hash (hash)
-  {
-    var text = hash.slice (1);
-    /* Some anchor elements are present in 'config.INDEX_NAME' and we need to
-       handle link to them specially (i.e. not try to find their corresponding
-       iframe).*/
-    if (config.MAIN_ANCHORS.includes (text))
-      return config.INDEX_ID + "." + text;
-    else
-      return text;
-  }
-
-  /** Return an object composed of the filename and the anchor of LINKID.
-      LINKID can have the form "foobar.anchor" or just "foobar".
-      @arg {string} linkid
-      @return {{pageid: string, hash: string}} */
-  function
-  linkid_split (linkid)
-  {
-    if (!linkid.includes ("."))
-      return { pageid: linkid, hash: "" };
-    else
-      {
-        var ref = linkid.match (/^(.+)\.(.*)$/).slice (1);
-        return { pageid: ref[0], hash: "#" + ref[1] };
-      }
-  }
-
-  /** Convert LINKID which has the form "foobar.anchor" or just "foobar", to
-      an URL of the form `foobar${config.EXT}#anchor`.
-      @arg {string} linkid */
-  function
-  linkid_to_url (linkid)
-  {
-    if (linkid === config.INDEX_ID)
-      return config.INDEX_NAME;
-    else
-      {
-        var link = linkid_split (linkid);
-        return link.pageid + config.EXT + link.hash;
-      }
-  }
-
-  /** Check if 'URL' may be a cross-reference to another page in this manual. 
*/
-  function
-  maybe_pageref_url_p (url)
-  {
-    return url.match(config.LOCAL_HTML_PAGE_PATTERN);
-  }
-
-  /** Check if 'URL' is a link to another manual.  For locally installed 
-      manuals only. */
-  function
-  external_manual_url_p (url)
-  {
-    if (typeof url !== "string")
-      throw new TypeError ("'" + url + "' is not a string");
-
-    return url.match(/^..\//);
-  }
-
-  /** Return PATHNAME with any leading directory components removed.  If
-      specified, also remove a trailing SUFFIX.  */
-  function
-  basename (pathname, suffix)
-  {
-    var res = pathname.replace (/.*[/]/, "");
-    if (!suffix)
-      return res;
-    else if (suffix instanceof RegExp)
-      return res.replace (suffix, "");
-    else /* typeof SUFFIX === "string" */
-      return res.replace (new RegExp ("[.]" + suffix), "");
-  }
-
-  /** Strip last component from PATHNAME and keep the trailing slash. For
-      example if PATHNAME is "/foo/bar/baz.html" then return "/foo/bar/".
-      @arg {string} pathname */
-  function
-  dirname (pathname)
-  {
-    var res = pathname.match (/\/?.*\//);
-    if (res)
-      return res[0];
-    else
-      throw new Error ("'location.pathname' is not recognized");
-  }
-
-  /** Apply FUNC to each nodes in the NODE subtree.  The walk follows a depth
-      first algorithm.  Only consider the nodes of type NODE_TYPE.  */
-  function
-  depth_first_walk (node, func, node_type)
-  {
-    if (!node_type || (node.nodeType === node_type))
-      func (node);
-
-    for (var child = node.firstChild; child; child = child.nextSibling)
-      depth_first_walk (child, func, node_type);
-  }
-
-  /** Return the "effective" href attribute of a link (a) element. */
-  function
-  link_href (alink)
-  {
-    return alink._href || alink.getAttribute("href");
-  }
-
-  /** Return the hash part of HREF without the '#' prefix.  HREF must be a
-      string.  If there is no hash part in HREF then return the empty
-      string.  */
-  function
-  href_hash (href)
-  {
-    if (typeof href !== "string")
-      throw new TypeError (href + " is not a string");
-
-    if (href.includes ("#"))
-      return href.replace (/.*#/, "");
-    else
-      return "";
-  }
-
-  /** Check if LINKID corresponds to a page containing index links.  */
-  function
-  linkid_contains_index (linkid)
-  {
-    return linkid.match (/^.*-index$/i) || linkid.match (/^Index$/);
-  }
-
-  /** Retrieve PREV, NEXT, and UP links, and local menu from CONTENT and
-      return an object containing references to those links.  CONTENT must be
-      an object implementing the ParentNode interface (Element,
-      Document...).  */
-  function
-  navigation_links (content)
-  {
-    var links = content.querySelectorAll ("a[accesskey][href]");
-    var res = {};
-    /* links have the form MAIN_FILE.html#FRAME-ID.  For convenience
-       only store FRAME-ID.  */
-    for (var i = 0; i < links.length; i += 1)
-      {
-        var link = links[i];
-        var nav_id = navigation_links.dict[link.getAttribute ("accesskey")];
-        if (nav_id)
-          {
-            var href = basename (link_href (link));
-            if (href === config.INDEX_NAME)
-              res[nav_id] = config.INDEX_ID;
-            else
-              res[nav_id] = href_hash (href);
-          }
-        else /* this link is part of local table of content. */
-          {
-            res.menu = res.menu || {};
-            res.menu[link.text] = href_hash (link_href (link));
-          }
-      }
-
-      return res;
-  }
-
-  navigation_links.dict = { n: "next", p: "prev", u: "up" };
-
-  function
-  add_icons ()
-  {
-    var div = document.createElement ("div");
-    div.setAttribute ("id", "icon-bar");
-    var span = document.createElement ("span");
-    span.innerHTML = "?";
-    // Set tool-tip (on hover)
-    span.setAttribute ("title", "Help for keyboard shortcuts");
-    span.classList.add ("icon");
-    span.addEventListener ("click", function () {
-      store.dispatch (actions.show_help ());
-    }, false);
-    div.appendChild (span);
-    document.body.insertBefore (div, document.body.firstChild);
-  }
-
-  /** Check if ELEM matches SEARCH
-      @arg {Element} elem
-      @arg {RegExp} rgxp
-      @return {boolean} */
-  function
-  search (elem, rgxp)
-  {
-    /** @type {Text} */
-    var text = null;
-
-    /** @arg {Text} node */
-    function
-    find (node)
-    {
-      if (rgxp.test (node.textContent))
-        {
-          /* Ignore previous match.  */
-          var prev = node.parentElement.matches ("span.highlight");
-          text = (prev) ? null : (text || node);
-        }
-    }
-
-    depth_first_walk (elem, find, Node.TEXT_NODE);
-    remove_highlight (elem);
-    if (!text)
-      return false;
-    else
-      {
-        highlight_text (rgxp, text);
-        return true;
-      }
-  }
-
-  /** Find the pageid corresponding to forward direction.
-      @arg {any} state
-      @arg {string} linkid
-      @return {string} the forward pageid */
-  function
-  forward_pageid (state, linkid)
-  {
-    var data = state.loaded_nodes[linkid];
-    if (!data)
-      throw new Error ("page not loaded: " + linkid);
-    else if (!data.forward)
-      return null;
-    else
-      {
-        var cur = linkid_split (linkid);
-        var fwd = linkid_split (data.forward);
-        if (!fwd.hash && fwd.pageid !== cur.pageid)
-          return fwd.pageid;
-        else
-          return forward_pageid (state, data.forward);
-      }
-  }
-
-  /** Highlight text in NODE which match RGXP.
-      @arg {RegExp} rgxp
-      @arg {Text} node */
-  function
-  highlight_text (rgxp, node)
-  {
-    /* Skip elements corresponding to highlighted words to avoid infinite
-       recursion.  */
-    if (node.parentElement.matches ("span.highlight"))
-      return;
-
-    var matches = rgxp.exec (node.textContent);
-    if (matches)
-      {
-        /* Create an highlighted element containing first match.  */
-        var span = document.createElement ("span");
-        span.appendChild (document.createTextNode (matches[0]));
-        span.setAttribute ("id", "search-result");
-        span.classList.add ("highlight");
-
-        var right_node = node.splitText (matches.index);
-        /* Remove first match from right node.  */
-        right_node.textContent = right_node.textContent
-                                           .slice (matches[0].length);
-        node.parentElement.insertBefore (span, right_node);
-      }
-  }
-
-  /** Remove every highlighted elements and inline their text content.
-      @arg {Element} elem */
-  function
-  remove_highlight (elem)
-  {
-    var spans = elem.getElementsByClassName ("highlight");
-    /* Replace spans with their inner text node.  */
-    while (spans.length > 0)
-      {
-        var span = spans[0];
-        var parent = span.parentElement;
-        parent.replaceChild (span.firstChild, span);
-      }
-  }
-
-  /*--------------.
-  | Entry point.  |
-  `--------------*/
-
-  /** Depending on the role of the document launching this script, different
-      event handlers are registered.  This script can be used in the context 
of:
-
-      - the index page of the manual which manages the state of the application
-      - the iframe which contains the lateral table of content
-      - other iframes which contain other pages of the manual
-
-      This is done to allow referencing the same script inside every HTML page.
-      This has the benefits of reducing the number of HTTP requests required to
-      fetch the Javascript code and simplifying the work of the Texinfo HTML
-      converter.  */
-
-  /* Display MSG bail out message portably.  */
-  function
-  error (msg)
-  {
-    /* XXX: This code needs to be highly portable.
-       Check <https://quirksmode.org/dom/core/> for details.  */
-    return function () {
-        var div = document.createElement ("div");
-        div.setAttribute ("class", "error");
-        div.innerHTML = msg;
-        var elem = document.body.firstChild;
-        document.body.insertBefore (div, elem);
-        window.setTimeout (function () {
-          document.body.removeChild (div);
-        }, config.WARNING_TIMEOUT);
-      };
-  }
-
-  /* Check if current browser supports the minimum requirements required for
-     properly using this script, otherwise bails out.  */
-  if (features && !(features.es5
-                    && features.classlist
-                    && features.eventlistener
-                    && features.hidden
-                    && features.history
-                    && features.postmessage
-                    && features.queryselector))
-    {
-      window.onload = error ("'info.js' is not compatible with this browser");
-      return;
-    }
-
-  /* Until we have a responsive design implemented, fallback to basic
-     HTML navigation for small screen.  */
-    /*
-  if (window.screen.availWidth < config.SCREEN_MIN_WIDTH)
-    {
-      window.onload =
-        error ("screen width is too small to display the table of content");
-      return;
-    }
-*/
-
-  register_polyfills ();
-  /* Let the config provided by the user mask the default one.  */
-  config = Object.assign (config, user_config);
-
-  var inside_iframe = top !== window;
-  var inside_index_page = window.location.pathname === config.INDEX_NAME
-      || window.location.pathname.endsWith ("/" + config.INDEX_NAME)
-      || window.location.pathname.endsWith ("/");
-
-  if (inside_index_page)
-    {
-      var initial_state = {
-        /* Dictionary associating page ids to next, prev, up, forward,
-           backward link ids.  */
-        loaded_nodes: {},
-        /* Dictionary associating keyword to linkids.  */
-        index: undefined,
-        /* page id of the current page.  */
-        current: config.INDEX_ID,
-        /* dictionary associating a page id to a boolean.  */
-        ready: {},
-        /* Current mode for handling history.  */
-        history: "replaceState",
-        /* Define the name of current text input.  */
-        text_input: null
-      };
-
-      store = new Store (updater, initial_state);
-      var index = init_index_page ();
-      var sidebar = init_sidebar ();
-      window.addEventListener ("DOMContentLoaded", function () {
-        index.on_load ();
-        sidebar.on_load ();
-      }, false);
-      window.addEventListener ("message", index.on_message, false);
-      window.addEventListener ("message", sidebar.on_message, false);
-      window.onpopstate = index.on_popstate;
-    }
-  else if (inside_iframe)
-    {
-      store = new Remote_store ();
-      var iframe = init_iframe ();
-      window.addEventListener ("DOMContentLoaded", iframe.on_load, false);
-      window.addEventListener ("message", iframe.on_message, false);
-    }
-  else
-    {
-      /* Jump to 'config.INDEX_NAME' and adapt the selected iframe.  */
-      window.location.replace (with_sidebar_query (window.location.href));
-    }
-
-  /* Register common event handlers.  */
-  window.addEventListener ("beforeunload", on_unload, false);
-  window.addEventListener ("click", on_click, false);
-  /* XXX: handle 'keydown' event instead of 'keypress' since Chromium
-     doesn't handle the 'Escape' key properly.  See
-     https://bugs.chromium.org/p/chromium/issues/detail?id=9061.  */
-  window.addEventListener ("keydown", on_keydown, false);
-} (window["Modernizr"], window["INFO_CONFIG"]));
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/js/modernizr.js
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/js/modernizr.js
deleted file mode 100644
index 76c811597b..0000000000
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/js/modernizr.js
+++ /dev/null
@@ -1,767 +0,0 @@
-/*!
- * modernizr v3.5.0
- * Build 
https://modernizr.com/download?-classlist-datalistelem-es5-eventlistener-framed-hidden-history-postmessage-queryselector-dontmin
- *
- * Copyright (c)
- *  Faruk Ates
- *  Paul Irish
- *  Alex Sexton
- *  Ryan Seddon
- *  Patrick Kettner
- *  Stu Cox
- *  Richard Herrera
-
- * MIT License
- */
-
-/*
- * Modernizr tests which native CSS3 and HTML5 features are available in the
- * current UA and makes the results available to you in two ways: as 
properties on
- * a global `Modernizr` object, and as classes on the `<html>` element. This
- * information allows you to progressively enhance your pages with a granular 
level
- * of control over the experience.
-*/
-
-;(function(window, document, undefined){
-  var tests = [];
-  
-
-  /**
-   *
-   * ModernizrProto is the constructor for Modernizr
-   *
-   * @class
-   * @access public
-   */
-
-  var ModernizrProto = {
-    // The current version, dummy
-    _version: '3.5.0',
-
-    // Any settings that don't work as separate modules
-    // can go in here as configuration.
-    _config: {
-      'classPrefix': '',
-      'enableClasses': true,
-      'enableJSClass': true,
-      'usePrefixes': true
-    },
-
-    // Queue of tests
-    _q: [],
-
-    // Stub these for people who are listening
-    on: function(test, cb) {
-      // I don't really think people should do this, but we can
-      // safe guard it a bit.
-      // -- NOTE:: this gets WAY overridden in src/addTest for actual async 
tests.
-      // This is in case people listen to synchronous tests. I would leave it 
out,
-      // but the code to *disallow* sync tests in the real version of this
-      // function is actually larger than this.
-      var self = this;
-      setTimeout(function() {
-        cb(self[test]);
-      }, 0);
-    },
-
-    addTest: function(name, fn, options) {
-      tests.push({name: name, fn: fn, options: options});
-    },
-
-    addAsyncTest: function(fn) {
-      tests.push({name: null, fn: fn});
-    }
-  };
-
-  
-
-  // Fake some of Object.create so we can force non test results to be non 
"own" properties.
-  var Modernizr = function() {};
-  Modernizr.prototype = ModernizrProto;
-
-  // Leak modernizr globally when you `require` it rather than force it here.
-  // Overwrite name so constructor name is nicer :D
-  Modernizr = new Modernizr();
-
-  
-
-  var classes = [];
-  
-
-  /**
-   * is returns a boolean if the typeof an obj is exactly type.
-   *
-   * @access private
-   * @function is
-   * @param {*} obj - A thing we want to check the type of
-   * @param {string} type - A string to compare the typeof against
-   * @returns {boolean}
-   */
-
-  function is(obj, type) {
-    return typeof obj === type;
-  }
-  ;
-
-  /**
-   * Run through all tests and detect their support in the current UA.
-   *
-   * @access private
-   */
-
-  function testRunner() {
-    var featureNames;
-    var feature;
-    var aliasIdx;
-    var result;
-    var nameIdx;
-    var featureName;
-    var featureNameSplit;
-
-    for (var featureIdx in tests) {
-      if (tests.hasOwnProperty(featureIdx)) {
-        featureNames = [];
-        feature = tests[featureIdx];
-        // run the test, throw the return value into the Modernizr,
-        // then based on that boolean, define an appropriate className
-        // and push it into an array of classes we'll join later.
-        //
-        // If there is no name, it's an 'async' test that is run,
-        // but not directly added to the object. That should
-        // be done with a post-run addTest call.
-        if (feature.name) {
-          featureNames.push(feature.name.toLowerCase());
-
-          if (feature.options && feature.options.aliases && 
feature.options.aliases.length) {
-            // Add all the aliases into the names list
-            for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; 
aliasIdx++) {
-              
featureNames.push(feature.options.aliases[aliasIdx].toLowerCase());
-            }
-          }
-        }
-
-        // Run the test, or use the raw value if it's not a function
-        result = is(feature.fn, 'function') ? feature.fn() : feature.fn;
-
-
-        // Set each of the names on the Modernizr object
-        for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) {
-          featureName = featureNames[nameIdx];
-          // Support dot properties as sub tests. We don't do checking to make 
sure
-          // that the implied parent tests have been added. You must call them 
in
-          // order (either in the test, or make the parent test a dependency).
-          //
-          // Cap it to TWO to make the logic simple and because who needs that 
kind of subtesting
-          // hashtag famous last words
-          featureNameSplit = featureName.split('.');
-
-          if (featureNameSplit.length === 1) {
-            Modernizr[featureNameSplit[0]] = result;
-          } else {
-            // cast to a Boolean, if not one already
-            if (Modernizr[featureNameSplit[0]] && 
!(Modernizr[featureNameSplit[0]] instanceof Boolean)) {
-              Modernizr[featureNameSplit[0]] = new 
Boolean(Modernizr[featureNameSplit[0]]);
-            }
-
-            Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result;
-          }
-
-          classes.push((result ? '' : 'no-') + featureNameSplit.join('-'));
-        }
-      }
-    }
-  }
-  ;
-
-  /**
-   * docElement is a convenience wrapper to grab the root element of the 
document
-   *
-   * @access private
-   * @returns {HTMLElement|SVGElement} The root element of the document
-   */
-
-  var docElement = document.documentElement;
-  
-/*!
-{
-  "name": "classList",
-  "caniuse": "classlist",
-  "property": "classlist",
-  "tags": ["dom"],
-  "builderAliases": ["dataview_api"],
-  "notes": [{
-    "name": "MDN Docs",
-    "href": "https://developer.mozilla.org/en/DOM/element.classList";
-  }]
-}
-!*/
-
-  Modernizr.addTest('classlist', 'classList' in docElement);
-
-
-  /**
-   * A convenience helper to check if the document we are running in is an SVG 
document
-   *
-   * @access private
-   * @returns {boolean}
-   */
-
-  var isSVG = docElement.nodeName.toLowerCase() === 'svg';
-  
-
-  /**
-   * createElement is a convenience wrapper around document.createElement. 
Since we
-   * use createElement all over the place, this allows for (slightly) smaller 
code
-   * as well as abstracting away issues with creating elements in contexts 
other than
-   * HTML documents (e.g. SVG documents).
-   *
-   * @access private
-   * @function createElement
-   * @returns {HTMLElement|SVGElement} An HTML or SVG element
-   */
-
-  function createElement() {
-    if (typeof document.createElement !== 'function') {
-      // This is the case in IE7, where the type of createElement is "object".
-      // For this reason, we cannot call apply() as Object is not a Function.
-      return document.createElement(arguments[0]);
-    } else if (isSVG) {
-      return document.createElementNS.call(document, 
'http://www.w3.org/2000/svg', arguments[0]);
-    } else {
-      return document.createElement.apply(document, arguments);
-    }
-  }
-
-  ;
-/*!
-{
-  "name": "[hidden] Attribute",
-  "property": "hidden",
-  "tags": ["dom"],
-  "notes": [{
-    "name": "WHATWG: The hidden attribute",
-    "href": "https://developers.whatwg.org/editing.html#the-hidden-attribute";
-  }, {
-    "name": "original implementation of detect code",
-    "href": 
"https://github.com/aFarkas/html5shiv/blob/bf4fcc4/src/html5shiv.js#L38";
-  }],
-  "polyfills": ["html5shiv"],
-  "authors": ["Ron Waldon (@jokeyrhyme)"]
-}
-!*/
-/* DOC
-Does the browser support the HTML5 [hidden] attribute?
-*/
-
-  Modernizr.addTest('hidden', 'hidden' in createElement('a'));
-
-
-  /**
-   * since we have a fairly large number of input tests that don't mutate the 
input
-   * we create a single element that can be shared with all of those tests for 
a
-   * minor perf boost
-   *
-   * @access private
-   * @returns {HTMLInputElement}
-   */
-  var inputElem = createElement('input');
-  
-/*!
-{
-  "name": "Input attributes",
-  "property": "input",
-  "tags": ["forms"],
-  "authors": ["Mike Taylor"],
-  "notes": [{
-    "name": "WHATWG spec",
-    "href": 
"https://html.spec.whatwg.org/multipage/forms.html#input-type-attr-summary";
-  }],
-  "knownBugs": ["Some blackberry devices report false positive for 
input.multiple"]
-}
-!*/
-/* DOC
-Detects support for HTML5 `<input>` element attributes and exposes Boolean 
subproperties with the results:
-
-```javascript
-Modernizr.input.autocomplete
-Modernizr.input.autofocus
-Modernizr.input.list
-Modernizr.input.max
-Modernizr.input.min
-Modernizr.input.multiple
-Modernizr.input.pattern
-Modernizr.input.placeholder
-Modernizr.input.required
-Modernizr.input.step
-```
-*/
-
-  // Run through HTML5's new input attributes to see if the UA understands any.
-  // Mike Taylr has created a comprehensive resource for testing these 
attributes
-  //   when applied to all input types:
-  //   miketaylr.com/code/input-type-attr.html
-
-  // Only input placeholder is tested while textarea's placeholder is not.
-  // Currently Safari 4 and Opera 11 have support only for the input 
placeholder
-  // Both tests are available in feature-detects/forms-placeholder.js
-
-  var inputattrs = 'autocomplete autofocus list placeholder max min multiple 
pattern required step'.split(' ');
-  var attrs = {};
-
-  Modernizr.input = (function(props) {
-    for (var i = 0, len = props.length; i < len; i++) {
-      attrs[ props[i] ] = !!(props[i] in inputElem);
-    }
-    if (attrs.list) {
-      // safari false positive's on datalist: webk.it/74252
-      // see also github.com/Modernizr/Modernizr/issues/146
-      attrs.list = !!(createElement('datalist') && window.HTMLDataListElement);
-    }
-    return attrs;
-  })(inputattrs);
-
-/*!
-{
-  "name": "datalist Element",
-  "caniuse": "datalist",
-  "property": "datalistelem",
-  "tags": ["elem"],
-  "builderAliases": ["elem_datalist"],
-  "warnings": ["This test is a dupe of Modernizr.input.list. Only around for 
legacy reasons."],
-  "notes": [{
-    "name": "CSS Tricks Article",
-    "href": 
"https://css-tricks.com/15346-relevant-dropdowns-polyfill-for-datalist/";
-  },{
-    "name": "Mike Taylor Code",
-    "href": "https://miketaylr.com/code/datalist.html";
-  }]
-}
-!*/
-
-  // lol. we already have a test for datalist built in! silly you.
-  // Leaving it around in case anyone's using it
-
-  Modernizr.addTest('datalistelem', Modernizr.input.list);
-
-/*!
-{
-  "name": "ES5 Array",
-  "property": "es5array",
-  "notes": [{
-    "name": "ECMAScript 5.1 Language Specification",
-    "href": "http://www.ecma-international.org/ecma-262/5.1/";
-  }],
-  "polyfills": ["es5shim"],
-  "authors": ["Ron Waldon (@jokeyrhyme)"],
-  "tags": ["es5"]
-}
-!*/
-/* DOC
-Check if browser implements ECMAScript 5 Array per specification.
-*/
-
-  Modernizr.addTest('es5array', function() {
-    return !!(Array.prototype &&
-      Array.prototype.every &&
-      Array.prototype.filter &&
-      Array.prototype.forEach &&
-      Array.prototype.indexOf &&
-      Array.prototype.lastIndexOf &&
-      Array.prototype.map &&
-      Array.prototype.some &&
-      Array.prototype.reduce &&
-      Array.prototype.reduceRight &&
-      Array.isArray);
-  });
-
-/*!
-{
-  "name": "ES5 Date",
-  "property": "es5date",
-  "notes": [{
-    "name": "ECMAScript 5.1 Language Specification",
-    "href": "http://www.ecma-international.org/ecma-262/5.1/";
-  }],
-  "polyfills": ["es5shim"],
-  "authors": ["Ron Waldon (@jokeyrhyme)"],
-  "tags": ["es5"]
-}
-!*/
-/* DOC
-Check if browser implements ECMAScript 5 Date per specification.
-*/
-
-  Modernizr.addTest('es5date', function() {
-    var isoDate = '2013-04-12T06:06:37.307Z',
-      canParseISODate = false;
-    try {
-      canParseISODate = !!Date.parse(isoDate);
-    } catch (e) {
-      // no ISO date parsing yet
-    }
-    return !!(Date.now &&
-      Date.prototype &&
-      Date.prototype.toISOString &&
-      Date.prototype.toJSON &&
-      canParseISODate);
-  });
-
-/*!
-{
-  "name": "ES5 Function",
-  "property": "es5function",
-  "notes": [{
-    "name": "ECMAScript 5.1 Language Specification",
-    "href": "http://www.ecma-international.org/ecma-262/5.1/";
-  }],
-  "polyfills": ["es5shim"],
-  "authors": ["Ron Waldon (@jokeyrhyme)"],
-  "tags": ["es5"]
-}
-!*/
-/* DOC
-Check if browser implements ECMAScript 5 Function per specification.
-*/
-
-  Modernizr.addTest('es5function', function() {
-    return !!(Function.prototype && Function.prototype.bind);
-  });
-
-/*!
-{
-  "name": "ES5 Object",
-  "property": "es5object",
-  "notes": [{
-    "name": "ECMAScript 5.1 Language Specification",
-    "href": "http://www.ecma-international.org/ecma-262/5.1/";
-  }],
-  "polyfills": ["es5shim", "es5sham"],
-  "authors": ["Ron Waldon (@jokeyrhyme)"],
-  "tags": ["es5"]
-}
-!*/
-/* DOC
-Check if browser implements ECMAScript 5 Object per specification.
-*/
-
-  Modernizr.addTest('es5object', function() {
-    return !!(Object.keys &&
-      Object.create &&
-      Object.getPrototypeOf &&
-      Object.getOwnPropertyNames &&
-      Object.isSealed &&
-      Object.isFrozen &&
-      Object.isExtensible &&
-      Object.getOwnPropertyDescriptor &&
-      Object.defineProperty &&
-      Object.defineProperties &&
-      Object.seal &&
-      Object.freeze &&
-      Object.preventExtensions);
-  });
-
-/*!
-{
-  "name": "ES5 Strict Mode",
-  "property": "strictmode",
-  "caniuse": "sctrict-mode",
-  "notes": [{
-    "name": "ECMAScript 5.1 Language Specification",
-    "href": "http://www.ecma-international.org/ecma-262/5.1/";
-  }],
-  "authors": ["@kangax"],
-  "tags": ["es5"],
-  "builderAliases": ["es5_strictmode"]
-}
-!*/
-/* DOC
-Check if browser implements ECMAScript 5 Object strict mode.
-*/
-
-  Modernizr.addTest('strictmode', (function() {'use strict'; return !this; 
})());
-
-/*!
-{
-  "name": "ES5 String",
-  "property": "es5string",
-  "notes": [{
-    "name": "ECMAScript 5.1 Language Specification",
-    "href": "http://www.ecma-international.org/ecma-262/5.1/";
-  }],
-  "polyfills": ["es5shim"],
-  "authors": ["Ron Waldon (@jokeyrhyme)"],
-  "tags": ["es5"]
-}
-!*/
-/* DOC
-Check if browser implements ECMAScript 5 String per specification.
-*/
-
-  Modernizr.addTest('es5string', function() {
-    return !!(String.prototype && String.prototype.trim);
-  });
-
-/*!
-{
-  "name": "JSON",
-  "property": "json",
-  "caniuse": "json",
-  "notes": [{
-    "name": "MDN documentation",
-    "href": "https://developer.mozilla.org/en-US/docs/Glossary/JSON";
-  }],
-  "polyfills": ["json2"]
-}
-!*/
-/* DOC
-Detects native support for JSON handling functions.
-*/
-
-  // this will also succeed if you've loaded the JSON2.js polyfill ahead of 
time
-  //   ... but that should be obvious. :)
-
-  Modernizr.addTest('json', 'JSON' in window && 'parse' in JSON && 'stringify' 
in JSON);
-
-/*!
-{
-  "name": "ES5 Syntax",
-  "property": "es5syntax",
-  "notes": [{
-    "name": "ECMAScript 5.1 Language Specification",
-    "href": "http://www.ecma-international.org/ecma-262/5.1/";
-  }, {
-    "name": "original implementation of detect code",
-    "href": "http://kangax.github.io/es5-compat-table/";
-  }],
-  "authors": ["Ron Waldon (@jokeyrhyme)"],
-  "warnings": ["This detect uses `eval()`, so CSP may be a problem."],
-  "tags": ["es5"]
-}
-!*/
-/* DOC
-Check if browser accepts ECMAScript 5 syntax.
-*/
-
-  Modernizr.addTest('es5syntax', function() {
-    var value, obj, stringAccess, getter, setter, reservedWords, 
zeroWidthChars;
-    try {
-      /* eslint no-eval: "off" */
-      // Property access on strings
-      stringAccess = eval('"foobar"[3] === "b"');
-      // Getter in property initializer
-      getter = eval('({ get x(){ return 1 } }).x === 1');
-      eval('({ set x(v){ value = v; } }).x = 1');
-      // Setter in property initializer
-      setter = value === 1;
-      // Reserved words as property names
-      eval('obj = ({ if: 1 })');
-      reservedWords = obj['if'] === 1;
-      // Zero-width characters in identifiers
-      zeroWidthChars = eval('_\u200c\u200d = true');
-
-      return stringAccess && getter && setter && reservedWords && 
zeroWidthChars;
-    } catch (ignore) {
-      return false;
-    }
-  });
-
-/*!
-{
-  "name": "ES5 Immutable Undefined",
-  "property": "es5undefined",
-  "notes": [{
-    "name": "ECMAScript 5.1 Language Specification",
-    "href": "http://www.ecma-international.org/ecma-262/5.1/";
-  }, {
-    "name": "original implementation of detect code",
-    "href": "http://kangax.github.io/es5-compat-table/";
-  }],
-  "authors": ["Ron Waldon (@jokeyrhyme)"],
-  "tags": ["es5"]
-}
-!*/
-/* DOC
-Check if browser prevents assignment to global `undefined` per ECMAScript 5.
-*/
-
-  Modernizr.addTest('es5undefined', function() {
-    var result, originalUndefined;
-    try {
-      originalUndefined = window.undefined;
-      window.undefined = 12345;
-      result = typeof window.undefined === 'undefined';
-      window.undefined = originalUndefined;
-    } catch (e) {
-      return false;
-    }
-    return result;
-  });
-
-/*!
-{
-  "name": "ES5",
-  "property": "es5",
-  "notes": [{
-    "name": "ECMAScript 5.1 Language Specification",
-    "href": "http://www.ecma-international.org/ecma-262/5.1/";
-  }],
-  "polyfills": ["es5shim", "es5sham"],
-  "authors": ["Ron Waldon (@jokeyrhyme)"],
-  "tags": ["es5"]
-}
-!*/
-/* DOC
-Check if browser implements everything as specified in ECMAScript 5.
-*/
-
-  Modernizr.addTest('es5', function() {
-    return !!(
-      Modernizr.es5array &&
-      Modernizr.es5date &&
-      Modernizr.es5function &&
-      Modernizr.es5object &&
-      Modernizr.strictmode &&
-      Modernizr.es5string &&
-      Modernizr.json &&
-      Modernizr.es5syntax &&
-      Modernizr.es5undefined
-    );
-  });
-
-/*!
-{
-  "name": "Event Listener",
-  "property": "eventlistener",
-  "authors": ["Andrew Betts (@triblondon)"],
-  "notes": [{
-    "name": "W3C Spec",
-    "href": 
"https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Registration-interfaces";
-  }],
-  "polyfills": ["eventlistener"]
-}
-!*/
-/* DOC
-Detects native support for addEventListener
-*/
-
-  Modernizr.addTest('eventlistener', 'addEventListener' in window);
-
-/*!
-{
-  "name": "History API",
-  "property": "history",
-  "caniuse": "history",
-  "tags": ["history"],
-  "authors": ["Hay Kranen", "Alexander Farkas"],
-  "notes": [{
-    "name": "W3C Spec",
-    "href": "https://www.w3.org/TR/html51/browsers.html#the-history-interface";
-  }, {
-    "name": "MDN documentation",
-    "href": "https://developer.mozilla.org/en-US/docs/Web/API/window.history";
-  }],
-  "polyfills": ["historyjs", "html5historyapi"]
-}
-!*/
-/* DOC
-Detects support for the History API for manipulating the browser session 
history.
-*/
-
-  Modernizr.addTest('history', function() {
-    // Issue #733
-    // The stock browser on Android 2.2 & 2.3, and 4.0.x returns positive on 
history support
-    // Unfortunately support is really buggy and there is no clean way to 
detect
-    // these bugs, so we fall back to a user agent sniff :(
-    var ua = navigator.userAgent;
-
-    // We only want Android 2 and 4.0, stock browser, and not Chrome which 
identifies
-    // itself as 'Mobile Safari' as well, nor Windows Phone (issue #1471).
-    if ((ua.indexOf('Android 2.') !== -1 ||
-        (ua.indexOf('Android 4.0') !== -1)) &&
-        ua.indexOf('Mobile Safari') !== -1 &&
-        ua.indexOf('Chrome') === -1 &&
-        ua.indexOf('Windows Phone') === -1 &&
-    // Since all documents on file:// share an origin, the History apis are
-    // blocked there as well
-        location.protocol !== 'file:'
-    ) {
-      return false;
-    }
-
-    // Return the regular check
-    return (window.history && 'pushState' in window.history);
-  });
-
-/*!
-{
-  "name": "postMessage",
-  "property": "postmessage",
-  "caniuse": "x-doc-messaging",
-  "notes": [{
-    "name": "W3C Spec",
-    "href": "http://www.w3.org/TR/html5/comms.html#posting-messages";
-  }],
-  "polyfills": ["easyxdm", "postmessage-jquery"]
-}
-!*/
-/* DOC
-Detects support for the `window.postMessage` protocol for cross-document 
messaging.
-*/
-
-  Modernizr.addTest('postmessage', 'postMessage' in window);
-
-/*!
-{
-  "name": "QuerySelector",
-  "property": "queryselector",
-  "caniuse": "queryselector",
-  "tags": ["queryselector"],
-  "authors": ["Andrew Betts (@triblondon)"],
-  "notes": [{
-    "name" : "W3C Selectors reference",
-    "href": "https://www.w3.org/TR/selectors-api/#queryselectorall";
-  }],
-  "polyfills": ["css-selector-engine"]
-}
-!*/
-/* DOC
-Detects support for querySelector.
-*/
-
-  Modernizr.addTest('queryselector', 'querySelector' in document && 
'querySelectorAll' in document);
-
-/*!
-{
-  "name": "Framed window",
-  "property": "framed",
-  "tags": ["window"],
-  "builderAliases": ["window_framed"]
-}
-!*/
-/* DOC
-Tests if page is iframed.
-*/
-
-  // github.com/Modernizr/Modernizr/issues/242
-
-  Modernizr.addTest('framed', window.location != top.location);
-
-
-  // Run each test
-  testRunner();
-
-  delete ModernizrProto.addTest;
-  delete ModernizrProto.addAsyncTest;
-
-  // Run the things that are supposed to run after the tests
-  for (var i = 0; i < Modernizr._q.length; i++) {
-    Modernizr._q[i]();
-  }
-
-  // Leak Modernizr namespace
-  window.Modernizr = Modernizr;
-
-
-;
-
-})(window, document);
\ No newline at end of file
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/chapter.xhtml
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/chapter.xhtml
index 89dd1a7151..88723289fe 100644
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/chapter.xhtml
+++ 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/chapter.xhtml
@@ -882,9 +882,7 @@ ul.mark-none {list-style-type: none}
 -->
 </style>
 
-<link rel="stylesheet" type="text/css" href="../js/info.css"/>
-<script src="../js/modernizr.js" type="text/javascript"></script>
-<script src="../js/info.js" type="text/javascript"></script>
+
 </head>
 
 <body lang="en">
@@ -4955,6 +4953,6 @@ Invalid use of @':
 </div>
 
 
-<a href="js_licenses.xhtml" rel="jslicense"><small>JavaScript license 
information</small></a>
+
 </body>
 </html>
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/chapter2.xhtml
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/chapter2.xhtml
index 5439812994..464a87076e 100644
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/chapter2.xhtml
+++ 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/chapter2.xhtml
@@ -868,9 +868,7 @@ th.sections-header-printindex {text-align:left; 
padding-left: 1em}
 -->
 </style>
 
-<link rel="stylesheet" type="text/css" href="../js/info.css"/>
-<script src="../js/modernizr.js" type="text/javascript"></script>
-<script src="../js/info.js" type="text/javascript"></script>
+
 </head>
 
 <body lang="en">
@@ -1429,6 +1427,6 @@ th.sections-header-printindex {text-align:left; 
padding-left: 1em}
 </div>
 
 
-<a href="js_licenses.xhtml" rel="jslicense"><small>JavaScript license 
information</small></a>
+
 </body>
 </html>
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting.xhtml
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting.xhtml
index 5a03c5f11e..d03f4f924d 100644
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting.xhtml
+++ 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting.xhtml
@@ -875,9 +875,7 @@ ul.mark-none {list-style-type: none}
 -->
 </style>
 
-<link rel="stylesheet" type="text/css" href="../js/info.css"/>
-<script src="../js/modernizr.js" type="text/javascript"></script>
-<script src="../js/info.js" type="text/javascript"></script>
+
 </head>
 
 <body lang="en">
@@ -3068,6 +3066,6 @@ html ''
 
 <a class="node" id="Top"></a><a class="top" id="Top-section"></a>
 
-<a href="js_licenses.xhtml" rel="jslicense"><small>JavaScript license 
information</small></a>
+
 </body>
 </html>
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_abt.xhtml
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_abt.xhtml
index b1c1c44c4e..9657add853 100644
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_abt.xhtml
+++ 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_abt.xhtml
@@ -861,9 +861,7 @@ td.name-direction-about {text-align:center}
 -->
 </style>
 
-<link rel="stylesheet" type="text/css" href="../js/info.css"/>
-<script src="../js/modernizr.js" type="text/javascript"></script>
-<script src="../js/info.js" type="text/javascript"></script>
+
 </head>
 
 <body lang="en">
@@ -971,6 +969,6 @@ td.name-direction-about {text-align:center}
 </ul>
 </div>
 
-<a href="js_licenses.xhtml" rel="jslicense"><small>JavaScript license 
information</small></a>
+
 </body>
 </html>
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_fot.xhtml
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_fot.xhtml
index 50a119cf7b..8e14d0a256 100644
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_fot.xhtml
+++ 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_fot.xhtml
@@ -855,9 +855,7 @@ g-roupe
 <meta name="viewport" content="width=device-width,initial-scale=1"/>
 
 
-<link rel="stylesheet" type="text/css" href="../js/info.css"/>
-<script src="../js/modernizr.js" type="text/javascript"></script>
-<script src="../js/info.js" type="text/javascript"></script>
+
 </head>
 
 <body lang="en">
@@ -897,6 +895,6 @@ g-roupe
 <p>in footnote</p>
 </div>
 
-<a href="js_licenses.xhtml" rel="jslicense"><small>JavaScript license 
information</small></a>
+
 </body>
 </html>
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_ovr.xhtml
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_ovr.xhtml
index 472ee1de10..88a0c2913d 100644
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_ovr.xhtml
+++ 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_ovr.xhtml
@@ -860,9 +860,7 @@ ul.toc-numbered-mark {list-style: none}
 -->
 </style>
 
-<link rel="stylesheet" type="text/css" href="../js/info.css"/>
-<script src="../js/modernizr.js" type="text/javascript"></script>
-<script src="../js/info.js" type="text/javascript"></script>
+
 </head>
 
 <body lang="en">
@@ -877,6 +875,6 @@ ul.toc-numbered-mark {list-style: none}
 </div>
 </div>
 
-<a href="js_licenses.xhtml" rel="jslicense"><small>JavaScript license 
information</small></a>
+
 </body>
 </html>
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_toc.xhtml
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_toc.xhtml
index 4f4f3d8007..89f74a41d0 100644
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_toc.xhtml
+++ 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/formatting_toc.xhtml
@@ -860,9 +860,7 @@ ul.toc-numbered-mark {list-style: none}
 -->
 </style>
 
-<link rel="stylesheet" type="text/css" href="../js/info.css"/>
-<script src="../js/modernizr.js" type="text/javascript"></script>
-<script src="../js/info.js" type="text/javascript"></script>
+
 </head>
 
 <body lang="en">
@@ -888,6 +886,6 @@ ul.toc-numbered-mark {list-style: none}
 </div>
 </div>
 
-<a href="js_licenses.xhtml" rel="jslicense"><small>JavaScript license 
information</small></a>
+
 </body>
 </html>
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/js_licenses.xhtml
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/js_licenses.xhtml
deleted file mode 100644
index d20d8280a9..0000000000
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/js_licenses.xhtml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml";><head><title>jslicense 
labels</title></head>
-<body>
-<table id="jslicense-labels1">
-<tr>
-<td><a href="js/info.js">js/info.js</a></td>
-<td><a href="http://www.gnu.org/licenses/gpl-3.0.html";>GNU General Public 
License 3.0 or later</a></td>
-<td><a href="js/info.js">js/info.js</a></td>
-</tr>
-<tr>
-<td><a href="js/modernizr.js">js/modernizr.js</a></td>
-<td><a href="http://www.jclark.com/xml/copying.txt";>Expat</a></td>
-<td><a href="js/modernizr.js">js/modernizr.js</a></td>
-</tr>
-</table>
-</body></html>
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/s_002d_002dect_002cion.xhtml
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/s_002d_002dect_002cion.xhtml
index 121f92c575..c1cead2b0d 100644
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/s_002d_002dect_002cion.xhtml
+++ 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/s_002d_002dect_002cion.xhtml
@@ -855,9 +855,7 @@ g-roupe
 <meta name="viewport" content="width=device-width,initial-scale=1"/>
 
 
-<link rel="stylesheet" type="text/css" href="../js/info.css"/>
-<script src="../js/modernizr.js" type="text/javascript"></script>
-<script src="../js/info.js" type="text/javascript"></script>
+
 </head>
 
 <body lang="en">
@@ -868,6 +866,6 @@ g-roupe
 </div>
 
 
-<a href="js_licenses.xhtml" rel="jslicense"><small>JavaScript license 
information</small></a>
+
 </body>
 </html>
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/subsection.xhtml
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/subsection.xhtml
index 429dc405c8..9bd9709eea 100644
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/subsection.xhtml
+++ 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/subsection.xhtml
@@ -855,9 +855,7 @@ g-roupe
 <meta name="viewport" content="width=device-width,initial-scale=1"/>
 
 
-<link rel="stylesheet" type="text/css" href="../js/info.css"/>
-<script src="../js/modernizr.js" type="text/javascript"></script>
-<script src="../js/info.js" type="text/javascript"></script>
+
 </head>
 
 <body lang="en">
@@ -869,6 +867,6 @@ g-roupe
 </div>
 
 
-<a href="js_licenses.xhtml" rel="jslicense"><small>JavaScript license 
information</small></a>
+
 </body>
 </html>
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/subsubsection-_0060_0060simple_002ddouble_002d_002d.xhtml
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/subsubsection-_0060_0060simple_002ddouble_002d_002d.xhtml
index a819214db1..515ec33787 100644
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/subsubsection-_0060_0060simple_002ddouble_002d_002d.xhtml
+++ 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/subsubsection-_0060_0060simple_002ddouble_002d_002d.xhtml
@@ -855,9 +855,7 @@ g-roupe
 <meta name="viewport" content="width=device-width,initial-scale=1"/>
 
 
-<link rel="stylesheet" type="text/css" href="../js/info.css"/>
-<script src="../js/modernizr.js" type="text/javascript"></script>
-<script src="../js/info.js" type="text/javascript"></script>
+
 </head>
 
 <body lang="en">
@@ -867,6 +865,6 @@ g-roupe
 </div>
 
 
-<a href="js_licenses.xhtml" rel="jslicense"><small>JavaScript license 
information</small></a>
+
 </body>
 </html>
diff --git 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/subsubsection-three_002d_002d_002dfour_002d_002d_002d_002d_0027_0027.xhtml
 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/subsubsection-three_002d_002d_002dfour_002d_002d_002d_002d_0027_0027.xhtml
index fcf6516aa3..e7dc3d49b0 100644
--- 
a/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/subsubsection-three_002d_002d_002dfour_002d_002d_002d_002d_0027_0027.xhtml
+++ 
b/tp/tests/layout/res_parser/formatting_epub_nodes/formatting_epub_package/EPUB/xhtml/subsubsection-three_002d_002d_002dfour_002d_002d_002d_002d_0027_0027.xhtml
@@ -855,9 +855,7 @@ g-roupe
 <meta name="viewport" content="width=device-width,initial-scale=1"/>
 
 
-<link rel="stylesheet" type="text/css" href="../js/info.css"/>
-<script src="../js/modernizr.js" type="text/javascript"></script>
-<script src="../js/info.js" type="text/javascript"></script>
+
 </head>
 
 <body lang="en">
@@ -867,6 +865,6 @@ g-roupe
 </div>
 
 
-<a href="js_licenses.xhtml" rel="jslicense"><small>JavaScript license 
information</small></a>
+
 </body>
 </html>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]