| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893 |
- "use strict";
- function Search(menu) {
- this.menu = menu;
- this.$search = document.getElementById('menu-search');
- this.$searchBox = document.getElementById('menu-search-box');
- this.$searchResults = document.getElementById('menu-search-results');
-
- this.loadBiblio();
-
- document.addEventListener('keydown', this.documentKeydown.bind(this));
-
- this.$searchBox.addEventListener('keydown', debounce(this.searchBoxKeydown.bind(this), { stopPropagation: true }));
- this.$searchBox.addEventListener('keyup', debounce(this.searchBoxKeyup.bind(this), { stopPropagation: true }));
- }
- Search.prototype.loadBiblio = function () {
- var $biblio = document.getElementById('menu-search-biblio');
- if (!$biblio) {
- this.biblio = [];
- } else {
- this.biblio = JSON.parse($biblio.textContent);
- this.biblio.clauses = this.biblio.filter(function (e) { return e.type === 'clause' });
- this.biblio.byId = this.biblio.reduce(function (map, entry) {
- map[entry.id] = entry;
- return map;
- }, {});
- }
- }
- Search.prototype.documentKeydown = function (e) {
- if (e.keyCode === 191) {
- e.preventDefault();
- e.stopPropagation();
- this.triggerSearch();
- }
- }
- Search.prototype.searchBoxKeydown = function (e) {
- e.stopPropagation();
- e.preventDefault();
- if (e.keyCode === 191 && e.target.value.length === 0) {
- e.preventDefault();
- } else if (e.keyCode === 13) {
- e.preventDefault();
- this.selectResult();
- }
- }
- Search.prototype.searchBoxKeyup = function (e) {
- if (e.keyCode === 13 || e.keyCode === 9) {
- return;
- }
-
- this.search(e.target.value);
- }
- Search.prototype.triggerSearch = function (e) {
- if (this.menu.isVisible()) {
- this._closeAfterSearch = false;
- } else {
- this._closeAfterSearch = true;
- this.menu.show();
- }
- this.$searchBox.focus();
- this.$searchBox.select();
- }
- // bit 12 - Set if the result starts with searchString
- // bits 8-11: 8 - number of chunks multiplied by 2 if cases match, otherwise 1.
- // bits 1-7: 127 - length of the entry
- // General scheme: prefer case sensitive matches with fewer chunks, and otherwise
- // prefer shorter matches.
- function relevance(result, searchString) {
- var relevance = 0;
-
- relevance = Math.max(0, 8 - result.match.chunks) << 7;
-
- if (result.match.caseMatch) {
- relevance *= 2;
- }
-
- if (result.match.prefix) {
- relevance += 2048
- }
-
- relevance += Math.max(0, 255 - result.entry.key.length);
-
- return relevance;
- }
- Search.prototype.search = function (searchString) {
- var s = Date.now();
- if (searchString === '') {
- this.displayResults([]);
- this.hideSearch();
- return;
- } else {
- this.showSearch();
- }
-
- if (searchString.length === 1) {
- this.displayResults([]);
- return;
- }
-
- var results;
- if (/^[\d\.]*$/.test(searchString)) {
- results = this.biblio.clauses.filter(function (clause) {
- return clause.number.substring(0, searchString.length) === searchString;
- }).map(function (clause) {
- return { entry: clause };
- });
- } else {
- results = [];
-
- for (var i = 0; i < this.biblio.length; i++) {
- var entry = this.biblio[i];
- if (!entry.key) {
- // biblio entries without a key aren't searchable
- continue;
- }
- var match = fuzzysearch(searchString, entry.key);
- if (match) {
- results.push({ entry: entry, match: match });
- }
- }
-
- results.forEach(function (result) {
- result.relevance = relevance(result, searchString);
- });
-
- results = results.sort(function (a, b) { return b.relevance - a.relevance });
- }
- if (results.length > 50) {
- results = results.slice(0, 50);
- }
-
- this.displayResults(results);
- }
- Search.prototype.hideSearch = function () {
- this.$search.classList.remove('active');
- }
- Search.prototype.showSearch = function () {
- this.$search.classList.add('active');
- }
- Search.prototype.selectResult = function () {
- var $first = this.$searchResults.querySelector('li:first-child a');
- if ($first) {
- document.location = $first.getAttribute('href');
- }
-
- this.$searchBox.value = '';
- this.$searchBox.blur();
- this.displayResults([]);
- this.hideSearch();
- if (this._closeAfterSearch) {
- this.menu.hide();
- }
- }
- Search.prototype.displayResults = function (results) {
- if (results.length > 0) {
- this.$searchResults.classList.remove('no-results');
-
- var html = '<ul>';
- results.forEach(function (result) {
- var entry = result.entry;
- var id = entry.id;
- var cssClass = '';
- var text = '';
- if (entry.type === 'clause') {
- var number = entry.number ? entry.number + ' ' : '';
- text = number + entry.key;
- cssClass = 'clause';
- id = entry.id;
- } else if (entry.type === 'production') {
- text = entry.key;
- cssClass = 'prod';
- id = entry.id;
- } else if (entry.type === 'op') {
- text = entry.key;
- cssClass = 'op';
- id = entry.id || entry.refId;
- } else if (entry.type === 'term') {
- text = entry.key;
- cssClass = 'term';
- id = entry.id || entry.refId;
- }
- if (text) {
- html += '<li class=menu-search-result-' + cssClass + '><a href="#' + id + '">' + text + '</a></li>'
- }
- });
- html += '</ul>'
- this.$searchResults.innerHTML = html;
- } else {
- this.$searchResults.innerHTML = '';
- this.$searchResults.classList.add('no-results');
- }
- }
- function Menu() {
- this.$toggle = document.getElementById('menu-toggle');
- this.$menu = document.getElementById('menu');
- this.$toc = document.querySelector('menu-toc > ol');
- this.$pins = document.querySelector('#menu-pins');
- this.$pinList = document.getElementById('menu-pins-list');
- this.$toc = document.querySelector('#menu-toc > ol');
- this.$specContainer = document.getElementById('spec-container');
- this.search = new Search(this);
-
- this._pinnedIds = {};
- this.loadPinEntries();
- // toggle menu
- this.$toggle.addEventListener('click', this.toggle.bind(this));
- // keydown events for pinned clauses
- document.addEventListener('keydown', this.documentKeydown.bind(this));
- // toc expansion
- var tocItems = this.$menu.querySelectorAll('#menu-toc li');
- for (var i = 0; i < tocItems.length; i++) {
- var $item = tocItems[i];
- $item.addEventListener('click', function($item, event) {
- $item.classList.toggle('active');
- event.stopPropagation();
- }.bind(null, $item));
- }
- // close toc on toc item selection
- var tocLinks = this.$menu.querySelectorAll('#menu-toc li > a');
- for (var i = 0; i < tocLinks.length; i++) {
- var $link = tocLinks[i];
- $link.addEventListener('click', function(event) {
- this.toggle();
- event.stopPropagation();
- }.bind(this));
- }
- // update active clause on scroll
- window.addEventListener('scroll', debounce(this.updateActiveClause.bind(this)));
- this.updateActiveClause();
- // prevent menu scrolling from scrolling the body
- this.$toc.addEventListener('wheel', function (e) {
- var target = e.currentTarget;
- var offTop = e.deltaY < 0 && target.scrollTop === 0;
- if (offTop) {
- e.preventDefault();
- }
- var offBottom = e.deltaY > 0
- && target.offsetHeight + target.scrollTop >= target.scrollHeight;
- if (offBottom) {
- e.preventDefault();
- }
- })
- }
- Menu.prototype.documentKeydown = function (e) {
- e.stopPropagation();
- if (e.keyCode === 80) {
- this.togglePinEntry();
- } else if (e.keyCode > 48 && e.keyCode < 58) {
- this.selectPin(e.keyCode - 49);
- }
- }
- Menu.prototype.updateActiveClause = function () {
- this.setActiveClause(findActiveClause(this.$specContainer))
- }
- Menu.prototype.setActiveClause = function (clause) {
- this.$activeClause = clause;
- this.revealInToc(this.$activeClause);
- }
- Menu.prototype.revealInToc = function (path) {
- var current = this.$toc.querySelectorAll('li.revealed');
- for (var i = 0; i < current.length; i++) {
- current[i].classList.remove('revealed');
- current[i].classList.remove('revealed-leaf');
- }
-
- var current = this.$toc;
- var index = 0;
- while (index < path.length) {
- var children = current.children;
- for (var i = 0; i < children.length; i++) {
- if ('#' + path[index].id === children[i].children[1].getAttribute('href') ) {
- children[i].classList.add('revealed');
- if (index === path.length - 1) {
- children[i].classList.add('revealed-leaf');
- var rect = children[i].getBoundingClientRect();
- this.$toc.getBoundingClientRect().top
- var tocRect = this.$toc.getBoundingClientRect();
- if (rect.top + 10 > tocRect.bottom) {
- this.$toc.scrollTop = this.$toc.scrollTop + (rect.top - tocRect.bottom) + (rect.bottom - rect.top);
- } else if (rect.top < tocRect.top) {
- this.$toc.scrollTop = this.$toc.scrollTop - (tocRect.top - rect.top);
- }
- }
- current = children[i].querySelector('ol');
- index++;
- break;
- }
- }
-
- }
- }
- function findActiveClause(root, path) {
- var clauses = new ClauseWalker(root);
- var $clause;
- var found = false;
- var path = path || [];
-
- while ($clause = clauses.nextNode()) {
- var rect = $clause.getBoundingClientRect();
- var $header = $clause.children[0];
- var marginTop = parseInt(getComputedStyle($header)["margin-top"]);
-
- if ((rect.top - marginTop) <= 0 && rect.bottom > 0) {
- found = true;
- return findActiveClause($clause, path.concat($clause)) || path;
- }
- }
-
- return path;
- }
- function ClauseWalker(root) {
- var previous;
- var treeWalker = document.createTreeWalker(
- root,
- NodeFilter.SHOW_ELEMENT,
- {
- acceptNode: function (node) {
- if (previous === node.parentNode) {
- return NodeFilter.FILTER_REJECT;
- } else {
- previous = node;
- }
- if (node.nodeName === 'EMU-CLAUSE' || node.nodeName === 'EMU-INTRO' || node.nodeName === 'EMU-ANNEX') {
- return NodeFilter.FILTER_ACCEPT;
- } else {
- return NodeFilter.FILTER_SKIP;
- }
- }
- },
- false
- );
-
- return treeWalker;
- }
- Menu.prototype.toggle = function () {
- this.$menu.classList.toggle('active');
- }
- Menu.prototype.show = function () {
- this.$menu.classList.add('active');
- }
- Menu.prototype.hide = function () {
- this.$menu.classList.remove('active');
- }
- Menu.prototype.isVisible = function() {
- return this.$menu.classList.contains('active');
- }
- Menu.prototype.showPins = function () {
- this.$pins.classList.add('active');
- }
- Menu.prototype.hidePins = function () {
- this.$pins.classList.remove('active');
- }
- Menu.prototype.addPinEntry = function (id) {
- var entry = this.search.biblio.byId[id];
- if (!entry) {
- // id was deleted after pin (or something) so remove it
- delete this._pinnedIds[id];
- this.persistPinEntries();
- return;
- }
- if (entry.type === 'clause') {
- var prefix;
- if (entry.number) {
- prefix = entry.number + ' ';
- } else {
- prefix = '';
- }
- this.$pinList.innerHTML += '<li><a href="#' + entry.id + '">' + prefix + entry.titleHTML + '</a></li>';
- } else {
- this.$pinList.innerHTML += '<li><a href="#' + entry.id + '">' + entry.key + '</a></li>';
- }
- if (Object.keys(this._pinnedIds).length === 0) {
- this.showPins();
- }
- this._pinnedIds[id] = true;
- this.persistPinEntries();
- }
- Menu.prototype.removePinEntry = function (id) {
- var item = this.$pinList.querySelector('a[href="#' + id + '"]').parentNode;
- this.$pinList.removeChild(item);
- delete this._pinnedIds[id];
- if (Object.keys(this._pinnedIds).length === 0) {
- this.hidePins();
- }
- this.persistPinEntries();
- }
- Menu.prototype.persistPinEntries = function () {
- try {
- if (!window.localStorage) return;
- } catch (e) {
- return;
- }
- localStorage.pinEntries = JSON.stringify(Object.keys(this._pinnedIds));
- }
- Menu.prototype.loadPinEntries = function () {
- try {
- if (!window.localStorage) return;
- } catch (e) {
- return;
- }
-
- var pinsString = window.localStorage.pinEntries;
- if (!pinsString) return;
- var pins = JSON.parse(pinsString);
- for(var i = 0; i < pins.length; i++) {
- this.addPinEntry(pins[i]);
- }
- }
- Menu.prototype.togglePinEntry = function (id) {
- if (!id) {
- id = this.$activeClause[this.$activeClause.length - 1].id;
- }
- if (this._pinnedIds[id]) {
- this.removePinEntry(id);
- } else {
- this.addPinEntry(id);
- }
- }
- Menu.prototype.selectPin = function (num) {
- document.location = this.$pinList.children[num].children[0].href;
- }
- var menu;
- function init() {
- menu = new Menu();
- var $container = document.getElementById('spec-container');
- $container.addEventListener('mouseover', debounce(function (e) {
- Toolbox.activateIfMouseOver(e);
- }));
- }
- document.addEventListener('DOMContentLoaded', init);
- function debounce(fn, opts) {
- opts = opts || {};
- var timeout;
- return function(e) {
- if (opts.stopPropagation) {
- e.stopPropagation();
- }
- var args = arguments;
- if (timeout) {
- clearTimeout(timeout);
- }
- timeout = setTimeout(function() {
- timeout = null;
- fn.apply(this, args);
- }.bind(this), 150);
- }
- }
- var CLAUSE_NODES = ['EMU-CLAUSE', 'EMU-INTRO', 'EMU-ANNEX'];
- function findLocalReferences ($elem) {
- var name = $elem.innerHTML;
- var references = [];
- var parentClause = $elem.parentNode;
- while (parentClause && CLAUSE_NODES.indexOf(parentClause.nodeName) === -1) {
- parentClause = parentClause.parentNode;
- }
- if(!parentClause) return;
- var vars = parentClause.querySelectorAll('var');
- for (var i = 0; i < vars.length; i++) {
- var $var = vars[i];
- if ($var.innerHTML === name) {
- references.push($var);
- }
- }
- return references;
- }
- function toggleFindLocalReferences($elem) {
- var references = findLocalReferences($elem);
- if ($elem.classList.contains('referenced')) {
- references.forEach(function ($reference) {
- $reference.classList.remove('referenced');
- });
- } else {
- references.forEach(function ($reference) {
- $reference.classList.add('referenced');
- });
- }
- }
- function installFindLocalReferences () {
- document.addEventListener('click', function (e) {
- if (e.target.nodeName === 'VAR') {
- toggleFindLocalReferences(e.target);
- }
- });
- }
- document.addEventListener('DOMContentLoaded', installFindLocalReferences);
- // The following license applies to the fuzzysearch function
- // The MIT License (MIT)
- // Copyright © 2015 Nicolas Bevacqua
- // Copyright © 2016 Brian Terlson
- // Permission is hereby granted, free of charge, to any person obtaining a copy of
- // this software and associated documentation files (the "Software"), to deal in
- // the Software without restriction, including without limitation the rights to
- // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- // the Software, and to permit persons to whom the Software is furnished to do so,
- // subject to the following conditions:
- // The above copyright notice and this permission notice shall be included in all
- // copies or substantial portions of the Software.
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- function fuzzysearch (searchString, haystack, caseInsensitive) {
- var tlen = haystack.length;
- var qlen = searchString.length;
- var chunks = 1;
- var finding = false;
- var prefix = true;
-
- if (qlen > tlen) {
- return false;
- }
-
- if (qlen === tlen) {
- if (searchString === haystack) {
- return { caseMatch: true, chunks: 1, prefix: true };
- } else if (searchString.toLowerCase() === haystack.toLowerCase()) {
- return { caseMatch: false, chunks: 1, prefix: true };
- } else {
- return false;
- }
- }
-
- outer: for (var i = 0, j = 0; i < qlen; i++) {
- var nch = searchString[i];
- while (j < tlen) {
- var targetChar = haystack[j++];
- if (targetChar === nch) {
- finding = true;
- continue outer;
- }
- if (finding) {
- chunks++;
- finding = false;
- }
- }
-
- if (caseInsensitive) { return false }
-
- return fuzzysearch(searchString.toLowerCase(), haystack.toLowerCase(), true);
- }
-
- return { caseMatch: !caseInsensitive, chunks: chunks, prefix: j <= qlen };
- }
- var Toolbox = {
- init: function () {
- this.$container = document.createElement('div');
- this.$container.classList.add('toolbox');
- this.$permalink = document.createElement('a');
- this.$permalink.textContent = 'Permalink';
- this.$pinLink = document.createElement('a');
- this.$pinLink.textContent = 'Pin';
- this.$pinLink.setAttribute('href', '#');
- this.$pinLink.addEventListener('click', function (e) {
- e.preventDefault();
- e.stopPropagation();
- menu.togglePinEntry(this.entry.id);
- }.bind(this));
- this.$refsLink = document.createElement('a');
- this.$refsLink.setAttribute('href', '#');
- this.$refsLink.addEventListener('click', function (e) {
- e.preventDefault();
- e.stopPropagation();
- referencePane.showReferencesFor(this.entry);
- }.bind(this));
- this.$container.appendChild(this.$permalink);
- this.$container.appendChild(this.$pinLink);
- this.$container.appendChild(this.$refsLink);
- document.body.appendChild(this.$container);
- },
- activate: function (el, entry, target) {
- if (el === this._activeEl) return;
- this.active = true;
- this.entry = entry;
- this.$container.classList.add('active');
- this.top = el.offsetTop - this.$container.offsetHeight - 10;
- this.left = el.offsetLeft;
- this.$container.setAttribute('style', 'left: ' + this.left + 'px; top: ' + this.top + 'px');
- this.updatePermalink();
- this.updateReferences();
- this._activeEl = el;
- if (this.top < document.body.scrollTop && el === target) {
- // don't scroll unless it's a small thing (< 200px)
- this.$container.scrollIntoView();
- }
- },
- updatePermalink: function () {
- this.$permalink.setAttribute('href', '#' + this.entry.id);
- },
- updateReferences: function () {
- this.$refsLink.textContent = 'References (' + this.entry.referencingIds.length + ')';
- },
- activateIfMouseOver: function (e) {
- var ref = this.findReferenceUnder(e.target);
- if (ref && (!this.active || e.pageY > this._activeEl.offsetTop)) {
- var entry = menu.search.biblio.byId[ref.id];
- this.activate(ref.element, entry, e.target);
- } else if (this.active && ((e.pageY < this.top) || e.pageY > (this._activeEl.offsetTop + this._activeEl.offsetHeight))) {
- this.deactivate();
- }
- },
- findReferenceUnder: function (el) {
- while (el) {
- var parent = el.parentNode;
- if (el.nodeName === 'H1' && parent.nodeName.match(/EMU-CLAUSE|EMU-ANNEX|EMU-INTRO/) && parent.id) {
- return { element: el, id: parent.id };
- } else if (el.nodeName.match(/EMU-(?!CLAUSE|XREF|ANNEX|INTRO)|DFN/) &&
- el.id && el.id[0] !== '_') {
- if (el.nodeName === 'EMU-FIGURE' || el.nodeName === 'EMU-TABLE' || el.nodeName === 'EMU-EXAMPLE') {
- // return the figcaption element
- return { element: el.children[0].children[0], id: el.id };
- } else if (el.nodeName === 'EMU-PRODUCTION') {
- // return the LHS non-terminal element
- return { element: el.children[0], id: el.id };
- } else {
- return { element: el, id: el.id };
- }
- }
- el = parent;
- }
- },
- deactivate: function () {
- this.$container.classList.remove('active');
- this._activeEl = null;
- this.activeElBounds = null;
- this.active = false;
- }
- }
- var referencePane = {
- init: function() {
- this.$container = document.createElement('div');
- this.$container.setAttribute('id', 'references-pane-container');
- var $spacer = document.createElement('div');
- $spacer.setAttribute('id', 'references-pane-spacer');
- this.$pane = document.createElement('div');
- this.$pane.setAttribute('id', 'references-pane');
- this.$container.appendChild($spacer);
- this.$container.appendChild(this.$pane);
- this.$header = document.createElement('div');
- this.$header.classList.add('menu-pane-header');
- this.$header.textContent = 'References to ';
- this.$headerRefId = document.createElement('a');
- this.$header.appendChild(this.$headerRefId);
- this.$closeButton = document.createElement('span');
- this.$closeButton.setAttribute('id', 'references-pane-close');
- this.$closeButton.addEventListener('click', function (e) {
- this.deactivate();
- }.bind(this));
- this.$header.appendChild(this.$closeButton);
- this.$pane.appendChild(this.$header);
- var tableContainer = document.createElement('div');
- tableContainer.setAttribute('id', 'references-pane-table-container');
- this.$table = document.createElement('table');
- this.$table.setAttribute('id', 'references-pane-table');
- this.$tableBody = this.$table.createTBody();
- tableContainer.appendChild(this.$table);
- this.$pane.appendChild(tableContainer);
- menu.$specContainer.appendChild(this.$container);
- },
- activate: function () {
- this.$container.classList.add('active');
- },
- deactivate: function () {
- this.$container.classList.remove('active');
- },
- showReferencesFor(entry) {
- this.activate();
- var newBody = document.createElement('tbody');
- var previousId;
- var previousCell;
- var dupCount = 0;
- this.$headerRefId.textContent = '#' + entry.id;
- this.$headerRefId.setAttribute('href', '#' + entry.id);
- entry.referencingIds.map(function (id) {
- var target = document.getElementById(id);
- var cid = findParentClauseId(target);
- var clause = menu.search.biblio.byId[cid];
- var dupCount = 0;
- return { id: id, clause: clause }
- }).sort(function (a, b) {
- return sortByClauseNumber(a.clause, b.clause);
- }).forEach(function (record, i) {
- if (previousId === record.clause.id) {
- previousCell.innerHTML += ' (<a href="#' + record.id + '">' + (dupCount + 2) + '</a>)';
- dupCount++;
- } else {
- var row = newBody.insertRow();
- var cell = row.insertCell();
- cell.innerHTML = record.clause.number;
- cell = row.insertCell();
- cell.innerHTML = '<a href="#' + record.id + '">' + record.clause.titleHTML + '</a>';
- previousCell = cell;
- previousId = record.clause.id;
- dupCount = 0;
- }
- }, this);
- this.$table.removeChild(this.$tableBody);
- this.$tableBody = newBody;
- this.$table.appendChild(this.$tableBody);
- }
- }
- function findParentClauseId(node) {
- while (node && node.nodeName !== 'EMU-CLAUSE' && node.nodeName !== 'EMU-INTRO' && node.nodeName !== 'EMU-ANNEX') {
- node = node.parentNode;
- }
- if (!node) return null;
- return node.getAttribute('id');
- }
- function sortByClauseNumber(c1, c2) {
- var c1c = c1.number.split('.');
- var c2c = c2.number.split('.');
- for (var i = 0; i < c1c.length; i++) {
- if (i >= c2c.length) {
- return 1;
- }
-
- var c1 = c1c[i];
- var c2 = c2c[i];
- var c1cn = Number(c1);
- var c2cn = Number(c2);
- if (Number.isNaN(c1cn) && Number.isNaN(c2cn)) {
- if (c1 > c2) {
- return 1;
- } else if (c1 < c2) {
- return -1;
- }
- } else if (!Number.isNaN(c1cn) && Number.isNaN(c2cn)) {
- return -1;
- } else if (Number.isNaN(c1cn) && !Number.isNaN(c2cn)) {
- return 1;
- } else if(c1cn > c2cn) {
- return 1;
- } else if (c1cn < c2cn) {
- return -1;
- }
- }
- if (c1c.length === c2c.length) {
- return 0;
- }
- return -1;
- }
- document.addEventListener('DOMContentLoaded', function () {
- Toolbox.init();
- referencePane.init();
- })
- var CLAUSE_NODES = ['EMU-CLAUSE', 'EMU-INTRO', 'EMU-ANNEX'];
- function findLocalReferences ($elem) {
- var name = $elem.innerHTML;
- var references = [];
- var parentClause = $elem.parentNode;
- while (parentClause && CLAUSE_NODES.indexOf(parentClause.nodeName) === -1) {
- parentClause = parentClause.parentNode;
- }
- if(!parentClause) return;
- var vars = parentClause.querySelectorAll('var');
- for (var i = 0; i < vars.length; i++) {
- var $var = vars[i];
- if ($var.innerHTML === name) {
- references.push($var);
- }
- }
- return references;
- }
- function toggleFindLocalReferences($elem) {
- var references = findLocalReferences($elem);
- if ($elem.classList.contains('referenced')) {
- references.forEach(function ($reference) {
- $reference.classList.remove('referenced');
- });
- } else {
- references.forEach(function ($reference) {
- $reference.classList.add('referenced');
- });
- }
- }
- function installFindLocalReferences () {
- document.addEventListener('click', function (e) {
- if (e.target.nodeName === 'VAR') {
- toggleFindLocalReferences(e.target);
- }
- });
- }
- document.addEventListener('DOMContentLoaded', installFindLocalReferences);
|