1// A fork of https://resources.whatwg.org/dfn.js which works for HTML's multipage version by using xrefs.json. 2'use strict'; 3 4(function() { 5 6var isMultipage = document.documentElement.classList.contains('split'); 7var dfnMapDone = false; 8var dfnMap = {}; 9var dfnPanel; 10 11function isCrossSpecDfn(dfn) { 12 return dfn.firstChild && dfn.firstChild instanceof HTMLAnchorElement; 13} 14 15function handleClick(event) { 16 if (event.button !== 0) { 17 return; 18 } 19 var current = event.target; 20 var node; 21 var eventInDfnPanel = false; 22 while (current) { 23 if (current.matches( 24 "dfn, h2[data-dfn-type], h3[data-dfn-type], h4[data-dfn-type], h5[data-dfn-type], h6[data-dfn-type]" 25 )) { 26 node = current; 27 } 28 if (dfnPanel && current === dfnPanel) { 29 eventInDfnPanel = true; 30 } 31 current = current.parentElement; 32 } 33 if (!eventInDfnPanel) { 34 closePanel(); 35 } 36 if (!node) { 37 return; 38 } 39 var id = node.id || node.parentNode.id; 40 var path = ''; 41 if (isMultipage) { 42 path = location.pathname; 43 } 44 var specURL = ''; 45 if (isCrossSpecDfn(node)) { 46 specURL = node.firstChild.href; 47 event.preventDefault(); 48 } 49 loadReferences(id, path, specURL); 50 node.appendChild(dfnPanel); 51 if (isMultipage) { 52 sessionStorage.dfnId = id; 53 sessionStorage.dfnPath = path; 54 sessionStorage.dfnSpecURL = specURL; 55 } 56} 57 58function loadReferences(id, path, specURL) { 59 if (dfnPanel) { 60 dfnPanel.remove(); 61 dfnPanel = null; 62 } 63 dfnPanel = createPanel(id, path, specURL); 64 var p = document.createElement('p'); 65 dfnPanel.appendChild(p); 66 if (!dfnMapDone) { 67 p.textContent = 'Loading cross-referencesâ¦'; 68 import('./xrefs.json', { with: { type: 'json' } }) 69 .then(module => { 70 dfnMap = module.default; 71 dfnMapDone = true; 72 if (dfnPanel) { 73 fillInReferences(id); 74 } 75 }).catch(err => { 76 p.textContent = 'Error loading cross-references.'; 77 }); 78 } else { 79 fillInReferences(id); 80 } 81} 82 83function createPanel(id, path, specURL) { 84 var panel = document.createElement('div'); 85 panel.className = 'dfn-panel on'; 86 if (id) { 87 var permalinkP = document.createElement('p'); 88 var permalinkA = document.createElement('a'); 89 permalinkA.href = path + '#' + id; 90 permalinkA.onclick = closePanel; 91 permalinkA.textContent = '#' + id; 92 permalinkP.appendChild(permalinkA); 93 panel.appendChild(permalinkP); 94 } 95 if (specURL) { 96 var realLinkP = document.createElement('p'); 97 realLinkP.className = 'spec-link'; 98 realLinkP.textContent = 'Spec: '; 99 var realLinkA = document.createElement('a'); 100 realLinkA.href = specURL; 101 realLinkA.onclick = closePanel; 102 realLinkA.textContent = specURL; 103 realLinkP.appendChild(realLinkA); 104 panel.appendChild(realLinkP); 105 } 106 panel.dataset.id = id; 107 return panel; 108} 109 110function fillInReferences(id) { 111 var p = dfnPanel.lastChild; 112 if (id in dfnMap) { 113 p.textContent = 'Referenced in:'; 114 var ul = document.createElement('ul'); 115 var anchorMap = dfnMap[id]; 116 for (var header in anchorMap) { 117 var li = document.createElement('li'); 118 for (var i = 0; i < anchorMap[header].length; i += 1) { 119 var a = document.createElement('a'); 120 a.onclick = movePanel; 121 a.href = anchorMap[header][i]; 122 if (!isMultipage) { 123 a.href = a.href.substring(a.href.indexOf('#')); 124 } 125 if (i === 0) { 126 var headerFormatted = header.replace(/</g, '<'); 127 headerFormatted = headerFormatted.replace(/ ([^ ]+) (element(?!s)|attribute(?!s)|interface(?!s)|common interface|object)/g, ' <code>$1</code> $2'); 128 headerFormatted = headerFormatted.replace(/<code>(Before|After|Other|The|on|an|for|user|User|custom|Custom|built-in|abstract|exotic|global|settings|Browser|Serializable|Transferable|HTML|IDL|document)<\/code>/, '$1'); 129 headerFormatted = headerFormatted.replace(/(type=[^\)]+)/g, '<code>$1</code>'); 130 headerFormatted = headerFormatted.replace(/(Link type) "([^"]+)"/g, '$1 "<code>$2</code>"'); 131 headerFormatted = headerFormatted.replace(/(ImageBitmap|WindowOrWorkerGlobalScope|multipart\/x-mixed-replace|registerProtocolHandler\(\)|registerContentHandler\(\))|storage|/, '<code>$1</code>'); 132 a.innerHTML = headerFormatted; 133 } else { 134 li.appendChild(document.createTextNode(' ')); 135 a.appendChild(document.createTextNode('(' + (i + 1) + ')')); 136 } 137 li.appendChild(a); 138 } 139 ul.appendChild(li); 140 } 141 dfnPanel.appendChild(ul); 142 } else { 143 p.textContent = 'No references in this specification.'; 144 } 145} 146 147function closePanel(event) { 148 if (dfnPanel) { 149 dfnPanel.remove(); 150 dfnPanel = null; 151 } 152 if (event) { 153 event.stopPropagation(); 154 } 155 if (isMultipage) { 156 delete sessionStorage.dfnId; 157 delete sessionStorage.dfnPath; 158 delete sessionStorage.dfnSpecURL; 159 } 160} 161 162function movePanel(event) { 163 if (!dfnPanel) { 164 return; 165 } 166 dfnPanel.classList.add("activated"); 167 if (event) { 168 event.stopPropagation(); 169 } 170} 171 172function restoreOrClosePanelOnNav(event) { 173 // Invoking this function twice is fine since on the second invocation, 174 // if the panel is open, `dfnPanel.dataset.id === id` so nothing happens; 175 // if the panel is closed, it will call `closePanel` which only clean up 176 // sessionStorage (which should already be cleared in that case). 177 if (sessionStorage.dfnId) { 178 var id = sessionStorage.dfnId; 179 var path = sessionStorage.dfnPath; 180 var specURL = sessionStorage.dfnSpecURL; 181 if (!dfnPanel || (dfnPanel && dfnPanel.dataset.id !== id)) { 182 loadReferences(id, path, specURL); 183 movePanel(); 184 document.body.insertBefore(dfnPanel, document.body.firstChild); 185 } 186 } else { 187 closePanel(); 188 } 189} 190 191document.addEventListener('click', handleClick); 192if (isMultipage) { 193 document.addEventListener('DOMContentLoaded', restoreOrClosePanelOnNav); 194 // Also listen for pageshow to handle history navigation without page-reload. 195 window.addEventListener('pageshow', restoreOrClosePanelOnNav); 196} 197 198})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.