source: trip-planner-front/node_modules/reflect-metadata/docs/ecmarkup.js@ 6a80231

Last change on this file since 6a80231 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 24.7 KB
Line 
1"use strict";
2
3function Search(menu) {
4 this.menu = menu;
5 this.$search = document.getElementById('menu-search');
6 this.$searchBox = document.getElementById('menu-search-box');
7 this.$searchResults = document.getElementById('menu-search-results');
8
9 this.loadBiblio();
10
11 document.addEventListener('keydown', this.documentKeydown.bind(this));
12
13 this.$searchBox.addEventListener('keydown', debounce(this.searchBoxKeydown.bind(this), { stopPropagation: true }));
14 this.$searchBox.addEventListener('keyup', debounce(this.searchBoxKeyup.bind(this), { stopPropagation: true }));
15}
16
17Search.prototype.loadBiblio = function () {
18 var $biblio = document.getElementById('menu-search-biblio');
19 if (!$biblio) {
20 this.biblio = [];
21 } else {
22 this.biblio = JSON.parse($biblio.textContent);
23 this.biblio.clauses = this.biblio.filter(function (e) { return e.type === 'clause' });
24 this.biblio.byId = this.biblio.reduce(function (map, entry) {
25 map[entry.id] = entry;
26 return map;
27 }, {});
28 }
29}
30
31Search.prototype.documentKeydown = function (e) {
32 if (e.keyCode === 191) {
33 e.preventDefault();
34 e.stopPropagation();
35 this.triggerSearch();
36 }
37}
38
39Search.prototype.searchBoxKeydown = function (e) {
40 e.stopPropagation();
41 e.preventDefault();
42 if (e.keyCode === 191 && e.target.value.length === 0) {
43 e.preventDefault();
44 } else if (e.keyCode === 13) {
45 e.preventDefault();
46 this.selectResult();
47 }
48}
49
50Search.prototype.searchBoxKeyup = function (e) {
51 if (e.keyCode === 13 || e.keyCode === 9) {
52 return;
53 }
54
55 this.search(e.target.value);
56}
57
58
59Search.prototype.triggerSearch = function (e) {
60 if (this.menu.isVisible()) {
61 this._closeAfterSearch = false;
62 } else {
63 this._closeAfterSearch = true;
64 this.menu.show();
65 }
66
67 this.$searchBox.focus();
68 this.$searchBox.select();
69}
70// bit 12 - Set if the result starts with searchString
71// bits 8-11: 8 - number of chunks multiplied by 2 if cases match, otherwise 1.
72// bits 1-7: 127 - length of the entry
73// General scheme: prefer case sensitive matches with fewer chunks, and otherwise
74// prefer shorter matches.
75function relevance(result, searchString) {
76 var relevance = 0;
77
78 relevance = Math.max(0, 8 - result.match.chunks) << 7;
79
80 if (result.match.caseMatch) {
81 relevance *= 2;
82 }
83
84 if (result.match.prefix) {
85 relevance += 2048
86 }
87
88 relevance += Math.max(0, 255 - result.entry.key.length);
89
90 return relevance;
91}
92
93Search.prototype.search = function (searchString) {
94 var s = Date.now();
95
96 if (searchString === '') {
97 this.displayResults([]);
98 this.hideSearch();
99 return;
100 } else {
101 this.showSearch();
102 }
103
104 if (searchString.length === 1) {
105 this.displayResults([]);
106 return;
107 }
108
109 var results;
110
111 if (/^[\d\.]*$/.test(searchString)) {
112 results = this.biblio.clauses.filter(function (clause) {
113 return clause.number.substring(0, searchString.length) === searchString;
114 }).map(function (clause) {
115 return { entry: clause };
116 });
117 } else {
118 results = [];
119
120 for (var i = 0; i < this.biblio.length; i++) {
121 var entry = this.biblio[i];
122 if (!entry.key) {
123 // biblio entries without a key aren't searchable
124 continue;
125 }
126
127 var match = fuzzysearch(searchString, entry.key);
128 if (match) {
129 results.push({ entry: entry, match: match });
130 }
131 }
132
133 results.forEach(function (result) {
134 result.relevance = relevance(result, searchString);
135 });
136
137 results = results.sort(function (a, b) { return b.relevance - a.relevance });
138
139 }
140
141 if (results.length > 50) {
142 results = results.slice(0, 50);
143 }
144
145 this.displayResults(results);
146}
147Search.prototype.hideSearch = function () {
148 this.$search.classList.remove('active');
149}
150
151Search.prototype.showSearch = function () {
152 this.$search.classList.add('active');
153}
154
155Search.prototype.selectResult = function () {
156 var $first = this.$searchResults.querySelector('li:first-child a');
157
158 if ($first) {
159 document.location = $first.getAttribute('href');
160 }
161
162 this.$searchBox.value = '';
163 this.$searchBox.blur();
164 this.displayResults([]);
165 this.hideSearch();
166
167 if (this._closeAfterSearch) {
168 this.menu.hide();
169 }
170}
171
172Search.prototype.displayResults = function (results) {
173 if (results.length > 0) {
174 this.$searchResults.classList.remove('no-results');
175
176 var html = '<ul>';
177
178 results.forEach(function (result) {
179 var entry = result.entry;
180 var id = entry.id;
181 var cssClass = '';
182 var text = '';
183
184 if (entry.type === 'clause') {
185 var number = entry.number ? entry.number + ' ' : '';
186 text = number + entry.key;
187 cssClass = 'clause';
188 id = entry.id;
189 } else if (entry.type === 'production') {
190 text = entry.key;
191 cssClass = 'prod';
192 id = entry.id;
193 } else if (entry.type === 'op') {
194 text = entry.key;
195 cssClass = 'op';
196 id = entry.id || entry.refId;
197 } else if (entry.type === 'term') {
198 text = entry.key;
199 cssClass = 'term';
200 id = entry.id || entry.refId;
201 }
202
203 if (text) {
204 html += '<li class=menu-search-result-' + cssClass + '><a href="#' + id + '">' + text + '</a></li>'
205 }
206 });
207
208 html += '</ul>'
209
210 this.$searchResults.innerHTML = html;
211 } else {
212 this.$searchResults.innerHTML = '';
213 this.$searchResults.classList.add('no-results');
214 }
215}
216
217
218function Menu() {
219 this.$toggle = document.getElementById('menu-toggle');
220 this.$menu = document.getElementById('menu');
221 this.$toc = document.querySelector('menu-toc > ol');
222 this.$pins = document.querySelector('#menu-pins');
223 this.$pinList = document.getElementById('menu-pins-list');
224 this.$toc = document.querySelector('#menu-toc > ol');
225 this.$specContainer = document.getElementById('spec-container');
226 this.search = new Search(this);
227
228 this._pinnedIds = {};
229 this.loadPinEntries();
230
231 // toggle menu
232 this.$toggle.addEventListener('click', this.toggle.bind(this));
233
234 // keydown events for pinned clauses
235 document.addEventListener('keydown', this.documentKeydown.bind(this));
236
237 // toc expansion
238 var tocItems = this.$menu.querySelectorAll('#menu-toc li');
239 for (var i = 0; i < tocItems.length; i++) {
240 var $item = tocItems[i];
241 $item.addEventListener('click', function($item, event) {
242 $item.classList.toggle('active');
243 event.stopPropagation();
244 }.bind(null, $item));
245 }
246
247 // close toc on toc item selection
248 var tocLinks = this.$menu.querySelectorAll('#menu-toc li > a');
249 for (var i = 0; i < tocLinks.length; i++) {
250 var $link = tocLinks[i];
251 $link.addEventListener('click', function(event) {
252 this.toggle();
253 event.stopPropagation();
254 }.bind(this));
255 }
256
257 // update active clause on scroll
258 window.addEventListener('scroll', debounce(this.updateActiveClause.bind(this)));
259 this.updateActiveClause();
260
261 // prevent menu scrolling from scrolling the body
262 this.$toc.addEventListener('wheel', function (e) {
263 var target = e.currentTarget;
264 var offTop = e.deltaY < 0 && target.scrollTop === 0;
265 if (offTop) {
266 e.preventDefault();
267 }
268 var offBottom = e.deltaY > 0
269 && target.offsetHeight + target.scrollTop >= target.scrollHeight;
270
271 if (offBottom) {
272 e.preventDefault();
273 }
274 })
275}
276
277Menu.prototype.documentKeydown = function (e) {
278 e.stopPropagation();
279 if (e.keyCode === 80) {
280 this.togglePinEntry();
281 } else if (e.keyCode > 48 && e.keyCode < 58) {
282 this.selectPin(e.keyCode - 49);
283 }
284}
285
286Menu.prototype.updateActiveClause = function () {
287 this.setActiveClause(findActiveClause(this.$specContainer))
288}
289
290Menu.prototype.setActiveClause = function (clause) {
291 this.$activeClause = clause;
292 this.revealInToc(this.$activeClause);
293}
294
295Menu.prototype.revealInToc = function (path) {
296 var current = this.$toc.querySelectorAll('li.revealed');
297 for (var i = 0; i < current.length; i++) {
298 current[i].classList.remove('revealed');
299 current[i].classList.remove('revealed-leaf');
300 }
301
302 var current = this.$toc;
303 var index = 0;
304 while (index < path.length) {
305 var children = current.children;
306 for (var i = 0; i < children.length; i++) {
307 if ('#' + path[index].id === children[i].children[1].getAttribute('href') ) {
308 children[i].classList.add('revealed');
309 if (index === path.length - 1) {
310 children[i].classList.add('revealed-leaf');
311 var rect = children[i].getBoundingClientRect();
312 this.$toc.getBoundingClientRect().top
313 var tocRect = this.$toc.getBoundingClientRect();
314 if (rect.top + 10 > tocRect.bottom) {
315 this.$toc.scrollTop = this.$toc.scrollTop + (rect.top - tocRect.bottom) + (rect.bottom - rect.top);
316 } else if (rect.top < tocRect.top) {
317 this.$toc.scrollTop = this.$toc.scrollTop - (tocRect.top - rect.top);
318 }
319 }
320 current = children[i].querySelector('ol');
321 index++;
322 break;
323 }
324 }
325
326 }
327}
328
329function findActiveClause(root, path) {
330 var clauses = new ClauseWalker(root);
331 var $clause;
332 var found = false;
333 var path = path || [];
334
335 while ($clause = clauses.nextNode()) {
336 var rect = $clause.getBoundingClientRect();
337 var $header = $clause.children[0];
338 var marginTop = parseInt(getComputedStyle($header)["margin-top"]);
339
340 if ((rect.top - marginTop) <= 0 && rect.bottom > 0) {
341 found = true;
342 return findActiveClause($clause, path.concat($clause)) || path;
343 }
344 }
345
346 return path;
347}
348
349function ClauseWalker(root) {
350 var previous;
351 var treeWalker = document.createTreeWalker(
352 root,
353 NodeFilter.SHOW_ELEMENT,
354 {
355 acceptNode: function (node) {
356 if (previous === node.parentNode) {
357 return NodeFilter.FILTER_REJECT;
358 } else {
359 previous = node;
360 }
361 if (node.nodeName === 'EMU-CLAUSE' || node.nodeName === 'EMU-INTRO' || node.nodeName === 'EMU-ANNEX') {
362 return NodeFilter.FILTER_ACCEPT;
363 } else {
364 return NodeFilter.FILTER_SKIP;
365 }
366 }
367 },
368 false
369 );
370
371 return treeWalker;
372}
373
374Menu.prototype.toggle = function () {
375 this.$menu.classList.toggle('active');
376}
377
378Menu.prototype.show = function () {
379 this.$menu.classList.add('active');
380}
381
382Menu.prototype.hide = function () {
383 this.$menu.classList.remove('active');
384}
385
386Menu.prototype.isVisible = function() {
387 return this.$menu.classList.contains('active');
388}
389
390Menu.prototype.showPins = function () {
391 this.$pins.classList.add('active');
392}
393
394Menu.prototype.hidePins = function () {
395 this.$pins.classList.remove('active');
396}
397
398Menu.prototype.addPinEntry = function (id) {
399 var entry = this.search.biblio.byId[id];
400 if (!entry) {
401 // id was deleted after pin (or something) so remove it
402 delete this._pinnedIds[id];
403 this.persistPinEntries();
404 return;
405 }
406
407 if (entry.type === 'clause') {
408 var prefix;
409 if (entry.number) {
410 prefix = entry.number + ' ';
411 } else {
412 prefix = '';
413 }
414 this.$pinList.innerHTML += '<li><a href="#' + entry.id + '">' + prefix + entry.titleHTML + '</a></li>';
415 } else {
416 this.$pinList.innerHTML += '<li><a href="#' + entry.id + '">' + entry.key + '</a></li>';
417 }
418
419 if (Object.keys(this._pinnedIds).length === 0) {
420 this.showPins();
421 }
422 this._pinnedIds[id] = true;
423 this.persistPinEntries();
424}
425
426Menu.prototype.removePinEntry = function (id) {
427 var item = this.$pinList.querySelector('a[href="#' + id + '"]').parentNode;
428 this.$pinList.removeChild(item);
429 delete this._pinnedIds[id];
430 if (Object.keys(this._pinnedIds).length === 0) {
431 this.hidePins();
432 }
433
434 this.persistPinEntries();
435}
436
437Menu.prototype.persistPinEntries = function () {
438 try {
439 if (!window.localStorage) return;
440 } catch (e) {
441 return;
442 }
443
444 localStorage.pinEntries = JSON.stringify(Object.keys(this._pinnedIds));
445}
446
447Menu.prototype.loadPinEntries = function () {
448 try {
449 if (!window.localStorage) return;
450 } catch (e) {
451 return;
452 }
453
454 var pinsString = window.localStorage.pinEntries;
455 if (!pinsString) return;
456 var pins = JSON.parse(pinsString);
457 for(var i = 0; i < pins.length; i++) {
458 this.addPinEntry(pins[i]);
459 }
460}
461
462Menu.prototype.togglePinEntry = function (id) {
463 if (!id) {
464 id = this.$activeClause[this.$activeClause.length - 1].id;
465 }
466
467 if (this._pinnedIds[id]) {
468 this.removePinEntry(id);
469 } else {
470 this.addPinEntry(id);
471 }
472}
473
474Menu.prototype.selectPin = function (num) {
475 document.location = this.$pinList.children[num].children[0].href;
476}
477
478var menu;
479function init() {
480 menu = new Menu();
481 var $container = document.getElementById('spec-container');
482 $container.addEventListener('mouseover', debounce(function (e) {
483 Toolbox.activateIfMouseOver(e);
484 }));
485}
486
487document.addEventListener('DOMContentLoaded', init);
488
489function debounce(fn, opts) {
490 opts = opts || {};
491 var timeout;
492 return function(e) {
493 if (opts.stopPropagation) {
494 e.stopPropagation();
495 }
496 var args = arguments;
497 if (timeout) {
498 clearTimeout(timeout);
499 }
500 timeout = setTimeout(function() {
501 timeout = null;
502 fn.apply(this, args);
503 }.bind(this), 150);
504 }
505}
506
507var CLAUSE_NODES = ['EMU-CLAUSE', 'EMU-INTRO', 'EMU-ANNEX'];
508function findLocalReferences ($elem) {
509 var name = $elem.innerHTML;
510 var references = [];
511
512 var parentClause = $elem.parentNode;
513 while (parentClause && CLAUSE_NODES.indexOf(parentClause.nodeName) === -1) {
514 parentClause = parentClause.parentNode;
515 }
516
517 if(!parentClause) return;
518
519 var vars = parentClause.querySelectorAll('var');
520
521 for (var i = 0; i < vars.length; i++) {
522 var $var = vars[i];
523
524 if ($var.innerHTML === name) {
525 references.push($var);
526 }
527 }
528
529 return references;
530}
531
532function toggleFindLocalReferences($elem) {
533 var references = findLocalReferences($elem);
534 if ($elem.classList.contains('referenced')) {
535 references.forEach(function ($reference) {
536 $reference.classList.remove('referenced');
537 });
538 } else {
539 references.forEach(function ($reference) {
540 $reference.classList.add('referenced');
541 });
542 }
543}
544
545function installFindLocalReferences () {
546 document.addEventListener('click', function (e) {
547 if (e.target.nodeName === 'VAR') {
548 toggleFindLocalReferences(e.target);
549 }
550 });
551}
552
553document.addEventListener('DOMContentLoaded', installFindLocalReferences);
554
555
556
557
558// The following license applies to the fuzzysearch function
559// The MIT License (MIT)
560// Copyright © 2015 Nicolas Bevacqua
561// Copyright © 2016 Brian Terlson
562// Permission is hereby granted, free of charge, to any person obtaining a copy of
563// this software and associated documentation files (the "Software"), to deal in
564// the Software without restriction, including without limitation the rights to
565// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
566// the Software, and to permit persons to whom the Software is furnished to do so,
567// subject to the following conditions:
568
569// The above copyright notice and this permission notice shall be included in all
570// copies or substantial portions of the Software.
571
572// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
573// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
574// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
575// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
576// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
577// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
578function fuzzysearch (searchString, haystack, caseInsensitive) {
579 var tlen = haystack.length;
580 var qlen = searchString.length;
581 var chunks = 1;
582 var finding = false;
583 var prefix = true;
584
585 if (qlen > tlen) {
586 return false;
587 }
588
589 if (qlen === tlen) {
590 if (searchString === haystack) {
591 return { caseMatch: true, chunks: 1, prefix: true };
592 } else if (searchString.toLowerCase() === haystack.toLowerCase()) {
593 return { caseMatch: false, chunks: 1, prefix: true };
594 } else {
595 return false;
596 }
597 }
598
599 outer: for (var i = 0, j = 0; i < qlen; i++) {
600 var nch = searchString[i];
601 while (j < tlen) {
602 var targetChar = haystack[j++];
603 if (targetChar === nch) {
604 finding = true;
605 continue outer;
606 }
607 if (finding) {
608 chunks++;
609 finding = false;
610 }
611 }
612
613 if (caseInsensitive) { return false }
614
615 return fuzzysearch(searchString.toLowerCase(), haystack.toLowerCase(), true);
616 }
617
618 return { caseMatch: !caseInsensitive, chunks: chunks, prefix: j <= qlen };
619}
620
621var Toolbox = {
622 init: function () {
623 this.$container = document.createElement('div');
624 this.$container.classList.add('toolbox');
625 this.$permalink = document.createElement('a');
626 this.$permalink.textContent = 'Permalink';
627 this.$pinLink = document.createElement('a');
628 this.$pinLink.textContent = 'Pin';
629 this.$pinLink.setAttribute('href', '#');
630 this.$pinLink.addEventListener('click', function (e) {
631 e.preventDefault();
632 e.stopPropagation();
633 menu.togglePinEntry(this.entry.id);
634 }.bind(this));
635
636 this.$refsLink = document.createElement('a');
637 this.$refsLink.setAttribute('href', '#');
638 this.$refsLink.addEventListener('click', function (e) {
639 e.preventDefault();
640 e.stopPropagation();
641 referencePane.showReferencesFor(this.entry);
642 }.bind(this));
643 this.$container.appendChild(this.$permalink);
644 this.$container.appendChild(this.$pinLink);
645 this.$container.appendChild(this.$refsLink);
646 document.body.appendChild(this.$container);
647 },
648
649 activate: function (el, entry, target) {
650 if (el === this._activeEl) return;
651 this.active = true;
652 this.entry = entry;
653 this.$container.classList.add('active');
654 this.top = el.offsetTop - this.$container.offsetHeight - 10;
655 this.left = el.offsetLeft;
656 this.$container.setAttribute('style', 'left: ' + this.left + 'px; top: ' + this.top + 'px');
657 this.updatePermalink();
658 this.updateReferences();
659 this._activeEl = el;
660 if (this.top < document.body.scrollTop && el === target) {
661 // don't scroll unless it's a small thing (< 200px)
662 this.$container.scrollIntoView();
663 }
664 },
665
666 updatePermalink: function () {
667 this.$permalink.setAttribute('href', '#' + this.entry.id);
668 },
669
670 updateReferences: function () {
671 this.$refsLink.textContent = 'References (' + this.entry.referencingIds.length + ')';
672 },
673
674 activateIfMouseOver: function (e) {
675 var ref = this.findReferenceUnder(e.target);
676 if (ref && (!this.active || e.pageY > this._activeEl.offsetTop)) {
677 var entry = menu.search.biblio.byId[ref.id];
678 this.activate(ref.element, entry, e.target);
679 } else if (this.active && ((e.pageY < this.top) || e.pageY > (this._activeEl.offsetTop + this._activeEl.offsetHeight))) {
680 this.deactivate();
681 }
682 },
683
684 findReferenceUnder: function (el) {
685 while (el) {
686 var parent = el.parentNode;
687 if (el.nodeName === 'H1' && parent.nodeName.match(/EMU-CLAUSE|EMU-ANNEX|EMU-INTRO/) && parent.id) {
688 return { element: el, id: parent.id };
689 } else if (el.nodeName.match(/EMU-(?!CLAUSE|XREF|ANNEX|INTRO)|DFN/) &&
690 el.id && el.id[0] !== '_') {
691 if (el.nodeName === 'EMU-FIGURE' || el.nodeName === 'EMU-TABLE' || el.nodeName === 'EMU-EXAMPLE') {
692 // return the figcaption element
693 return { element: el.children[0].children[0], id: el.id };
694 } else if (el.nodeName === 'EMU-PRODUCTION') {
695 // return the LHS non-terminal element
696 return { element: el.children[0], id: el.id };
697 } else {
698 return { element: el, id: el.id };
699 }
700 }
701 el = parent;
702 }
703 },
704
705 deactivate: function () {
706 this.$container.classList.remove('active');
707 this._activeEl = null;
708 this.activeElBounds = null;
709 this.active = false;
710 }
711}
712
713var referencePane = {
714 init: function() {
715 this.$container = document.createElement('div');
716 this.$container.setAttribute('id', 'references-pane-container');
717
718 var $spacer = document.createElement('div');
719 $spacer.setAttribute('id', 'references-pane-spacer');
720
721 this.$pane = document.createElement('div');
722 this.$pane.setAttribute('id', 'references-pane');
723
724 this.$container.appendChild($spacer);
725 this.$container.appendChild(this.$pane);
726
727 this.$header = document.createElement('div');
728 this.$header.classList.add('menu-pane-header');
729 this.$header.textContent = 'References to ';
730 this.$headerRefId = document.createElement('a');
731 this.$header.appendChild(this.$headerRefId);
732 this.$closeButton = document.createElement('span');
733 this.$closeButton.setAttribute('id', 'references-pane-close');
734 this.$closeButton.addEventListener('click', function (e) {
735 this.deactivate();
736 }.bind(this));
737 this.$header.appendChild(this.$closeButton);
738
739 this.$pane.appendChild(this.$header);
740 var tableContainer = document.createElement('div');
741 tableContainer.setAttribute('id', 'references-pane-table-container');
742
743 this.$table = document.createElement('table');
744 this.$table.setAttribute('id', 'references-pane-table');
745
746 this.$tableBody = this.$table.createTBody();
747
748 tableContainer.appendChild(this.$table);
749 this.$pane.appendChild(tableContainer);
750
751 menu.$specContainer.appendChild(this.$container);
752 },
753
754 activate: function () {
755 this.$container.classList.add('active');
756 },
757
758 deactivate: function () {
759 this.$container.classList.remove('active');
760 },
761
762 showReferencesFor(entry) {
763 this.activate();
764 var newBody = document.createElement('tbody');
765 var previousId;
766 var previousCell;
767 var dupCount = 0;
768 this.$headerRefId.textContent = '#' + entry.id;
769 this.$headerRefId.setAttribute('href', '#' + entry.id);
770 entry.referencingIds.map(function (id) {
771 var target = document.getElementById(id);
772 var cid = findParentClauseId(target);
773 var clause = menu.search.biblio.byId[cid];
774 var dupCount = 0;
775 return { id: id, clause: clause }
776 }).sort(function (a, b) {
777 return sortByClauseNumber(a.clause, b.clause);
778 }).forEach(function (record, i) {
779 if (previousId === record.clause.id) {
780 previousCell.innerHTML += ' (<a href="#' + record.id + '">' + (dupCount + 2) + '</a>)';
781 dupCount++;
782 } else {
783 var row = newBody.insertRow();
784 var cell = row.insertCell();
785 cell.innerHTML = record.clause.number;
786 cell = row.insertCell();
787 cell.innerHTML = '<a href="#' + record.id + '">' + record.clause.titleHTML + '</a>';
788 previousCell = cell;
789 previousId = record.clause.id;
790 dupCount = 0;
791 }
792 }, this);
793 this.$table.removeChild(this.$tableBody);
794 this.$tableBody = newBody;
795 this.$table.appendChild(this.$tableBody);
796 }
797}
798function findParentClauseId(node) {
799 while (node && node.nodeName !== 'EMU-CLAUSE' && node.nodeName !== 'EMU-INTRO' && node.nodeName !== 'EMU-ANNEX') {
800 node = node.parentNode;
801 }
802 if (!node) return null;
803 return node.getAttribute('id');
804}
805
806function sortByClauseNumber(c1, c2) {
807 var c1c = c1.number.split('.');
808 var c2c = c2.number.split('.');
809
810 for (var i = 0; i < c1c.length; i++) {
811 if (i >= c2c.length) {
812 return 1;
813 }
814
815 var c1 = c1c[i];
816 var c2 = c2c[i];
817 var c1cn = Number(c1);
818 var c2cn = Number(c2);
819
820 if (Number.isNaN(c1cn) && Number.isNaN(c2cn)) {
821 if (c1 > c2) {
822 return 1;
823 } else if (c1 < c2) {
824 return -1;
825 }
826 } else if (!Number.isNaN(c1cn) && Number.isNaN(c2cn)) {
827 return -1;
828 } else if (Number.isNaN(c1cn) && !Number.isNaN(c2cn)) {
829 return 1;
830 } else if(c1cn > c2cn) {
831 return 1;
832 } else if (c1cn < c2cn) {
833 return -1;
834 }
835 }
836
837 if (c1c.length === c2c.length) {
838 return 0;
839 }
840 return -1;
841}
842
843document.addEventListener('DOMContentLoaded', function () {
844 Toolbox.init();
845 referencePane.init();
846})
847var CLAUSE_NODES = ['EMU-CLAUSE', 'EMU-INTRO', 'EMU-ANNEX'];
848function findLocalReferences ($elem) {
849 var name = $elem.innerHTML;
850 var references = [];
851
852 var parentClause = $elem.parentNode;
853 while (parentClause && CLAUSE_NODES.indexOf(parentClause.nodeName) === -1) {
854 parentClause = parentClause.parentNode;
855 }
856
857 if(!parentClause) return;
858
859 var vars = parentClause.querySelectorAll('var');
860
861 for (var i = 0; i < vars.length; i++) {
862 var $var = vars[i];
863
864 if ($var.innerHTML === name) {
865 references.push($var);
866 }
867 }
868
869 return references;
870}
871
872function toggleFindLocalReferences($elem) {
873 var references = findLocalReferences($elem);
874 if ($elem.classList.contains('referenced')) {
875 references.forEach(function ($reference) {
876 $reference.classList.remove('referenced');
877 });
878 } else {
879 references.forEach(function ($reference) {
880 $reference.classList.add('referenced');
881 });
882 }
883}
884
885function installFindLocalReferences () {
886 document.addEventListener('click', function (e) {
887 if (e.target.nodeName === 'VAR') {
888 toggleFindLocalReferences(e.target);
889 }
890 });
891}
892
893document.addEventListener('DOMContentLoaded', installFindLocalReferences);
Note: See TracBrowser for help on using the repository browser.