| @@ -12,45 +12,49 @@ | ||
| 12 | 12 | * See the License for the specific language governing permissions and |
| 13 | 13 | * limitations under the License. |
| 14 | 14 | */ |
| 15 | 15 | |
| 16 | -'use strict'; | |
| 16 | +const { OPS } = globalThis.pdfjsLib || (await import("pdfjs-lib")); | |
| 17 | 17 | |
| 18 | -var FontInspector = (function FontInspectorClosure() { | |
| 19 | - var fonts; | |
| 20 | - var active = false; | |
| 21 | - var fontAttribute = 'data-font-name'; | |
| 18 | +const opMap = Object.create(null); | |
| 19 | +for (const key in OPS) { | |
| 20 | + opMap[OPS[key]] = key; | |
| 21 | +} | |
| 22 | + | |
| 23 | +const FontInspector = (function FontInspectorClosure() { | |
| 24 | + let fonts; | |
| 25 | + let active = false; | |
| 26 | + const fontAttribute = "data-font-name"; | |
| 22 | 27 | function removeSelection() { |
| 23 | - var divs = document.querySelectorAll('div[' + fontAttribute + ']'); | |
| 24 | - for (var i = 0, ii = divs.length; i < ii; ++i) { | |
| 25 | - var div = divs[i]; | |
| 26 | - div.className = ''; | |
| 28 | + const divs = document.querySelectorAll(`span[${fontAttribute}]`); | |
| 29 | + for (const div of divs) { | |
| 30 | + div.className = ""; | |
| 27 | 31 | } |
| 28 | 32 | } |
| 29 | 33 | function resetSelection() { |
| 30 | - var divs = document.querySelectorAll('div[' + fontAttribute + ']'); | |
| 31 | - for (var i = 0, ii = divs.length; i < ii; ++i) { | |
| 32 | - var div = divs[i]; | |
| 33 | - div.className = 'debuggerHideText'; | |
| 34 | + const divs = document.querySelectorAll(`span[${fontAttribute}]`); | |
| 35 | + for (const div of divs) { | |
| 36 | + div.className = "debuggerHideText"; | |
| 34 | 37 | } |
| 35 | 38 | } |
| 36 | 39 | function selectFont(fontName, show) { |
| 37 | - var divs = document.querySelectorAll('div[' + fontAttribute + '=' + | |
| 38 | - fontName + ']'); | |
| 39 | - for (var i = 0, ii = divs.length; i < ii; ++i) { | |
| 40 | - var div = divs[i]; | |
| 41 | - div.className = show ? 'debuggerShowText' : 'debuggerHideText'; | |
| 40 | + const divs = document.querySelectorAll( | |
| 41 | + `span[${fontAttribute}=${fontName}]` | |
| 42 | + ); | |
| 43 | + for (const div of divs) { | |
| 44 | + div.className = show ? "debuggerShowText" : "debuggerHideText"; | |
| 42 | 45 | } |
| 43 | 46 | } |
| 44 | 47 | function textLayerClick(e) { |
| 45 | - if (!e.target.dataset.fontName || | |
| 46 | - e.target.tagName.toUpperCase() !== 'DIV') { | |
| 48 | + if ( | |
| 49 | + !e.target.dataset.fontName || | |
| 50 | + e.target.tagName.toUpperCase() !== "SPAN" | |
| 51 | + ) { | |
| 47 | 52 | return; |
| 48 | 53 | } |
| 49 | - var fontName = e.target.dataset.fontName; | |
| 50 | - var selects = document.getElementsByTagName('input'); | |
| 51 | - for (var i = 0; i < selects.length; ++i) { | |
| 52 | - var select = selects[i]; | |
| 54 | + const fontName = e.target.dataset.fontName; | |
| 55 | + const selects = document.getElementsByTagName("input"); | |
| 56 | + for (const select of selects) { | |
| 53 | 57 | if (select.dataset.fontName !== fontName) { |
| 54 | 58 | continue; |
| 55 | 59 | } |
| 56 | 60 | select.checked = !select.checked; |
| @@ -59,25 +63,24 @@ | ||
| 59 | 63 | } |
| 60 | 64 | } |
| 61 | 65 | return { |
| 62 | 66 | // Properties/functions needed by PDFBug. |
| 63 | - id: 'FontInspector', | |
| 64 | - name: 'Font Inspector', | |
| 67 | + id: "FontInspector", | |
| 68 | + name: "Font Inspector", | |
| 65 | 69 | panel: null, |
| 66 | 70 | manager: null, |
| 67 | - init: function init(pdfjsLib) { | |
| 68 | - var panel = this.panel; | |
| 69 | - panel.setAttribute('style', 'padding: 5px;'); | |
| 70 | - var tmp = document.createElement('button'); | |
| 71 | - tmp.addEventListener('click', resetSelection); | |
| 72 | - tmp.textContent = 'Refresh'; | |
| 73 | - panel.appendChild(tmp); | |
| 71 | + init() { | |
| 72 | + const panel = this.panel; | |
| 73 | + const tmp = document.createElement("button"); | |
| 74 | + tmp.addEventListener("click", resetSelection); | |
| 75 | + tmp.textContent = "Refresh"; | |
| 76 | + panel.append(tmp); | |
| 74 | 77 | |
| 75 | - fonts = document.createElement('div'); | |
| 76 | - panel.appendChild(fonts); | |
| 78 | + fonts = document.createElement("div"); | |
| 79 | + panel.append(fonts); | |
| 77 | 80 | }, |
| 78 | - cleanup: function cleanup() { | |
| 79 | - fonts.textContent = ''; | |
| 81 | + cleanup() { | |
| 82 | + fonts.textContent = ""; | |
| 80 | 83 | }, |
| 81 | 84 | enabled: false, |
| 82 | 85 | get active() { |
| 83 | 86 | return active; |
| @@ -84,70 +87,73 @@ | ||
| 84 | 87 | }, |
| 85 | 88 | set active(value) { |
| 86 | 89 | active = value; |
| 87 | 90 | if (active) { |
| 88 | - document.body.addEventListener('click', textLayerClick, true); | |
| 91 | + document.body.addEventListener("click", textLayerClick, true); | |
| 89 | 92 | resetSelection(); |
| 90 | 93 | } else { |
| 91 | - document.body.removeEventListener('click', textLayerClick, true); | |
| 94 | + document.body.removeEventListener("click", textLayerClick, true); | |
| 92 | 95 | removeSelection(); |
| 93 | 96 | } |
| 94 | 97 | }, |
| 95 | 98 | // FontInspector specific functions. |
| 96 | - fontAdded: function fontAdded(fontObj, url) { | |
| 99 | + fontAdded(fontObj, url) { | |
| 97 | 100 | function properties(obj, list) { |
| 98 | - var moreInfo = document.createElement('table'); | |
| 99 | - for (var i = 0; i < list.length; i++) { | |
| 100 | - var tr = document.createElement('tr'); | |
| 101 | - var td1 = document.createElement('td'); | |
| 102 | - td1.textContent = list[i]; | |
| 103 | - tr.appendChild(td1); | |
| 104 | - var td2 = document.createElement('td'); | |
| 105 | - td2.textContent = obj[list[i]].toString(); | |
| 106 | - tr.appendChild(td2); | |
| 107 | - moreInfo.appendChild(tr); | |
| 101 | + const moreInfo = document.createElement("table"); | |
| 102 | + for (const entry of list) { | |
| 103 | + const tr = document.createElement("tr"); | |
| 104 | + const td1 = document.createElement("td"); | |
| 105 | + td1.textContent = entry; | |
| 106 | + tr.append(td1); | |
| 107 | + const td2 = document.createElement("td"); | |
| 108 | + td2.textContent = obj[entry].toString(); | |
| 109 | + tr.append(td2); | |
| 110 | + moreInfo.append(tr); | |
| 108 | 111 | } |
| 109 | 112 | return moreInfo; |
| 110 | 113 | } |
| 111 | - var moreInfo = properties(fontObj, ['name', 'type']); | |
| 112 | - var fontName = fontObj.loadedName; | |
| 113 | - var font = document.createElement('div'); | |
| 114 | - var name = document.createElement('span'); | |
| 114 | + | |
| 115 | + const moreInfo = fontObj.css | |
| 116 | + ? properties(fontObj, ["baseFontName"]) | |
| 117 | + : properties(fontObj, ["name", "type"]); | |
| 118 | + | |
| 119 | + const fontName = fontObj.loadedName; | |
| 120 | + const font = document.createElement("div"); | |
| 121 | + const name = document.createElement("span"); | |
| 115 | 122 | name.textContent = fontName; |
| 116 | - var download = document.createElement('a'); | |
| 117 | - if (url) { | |
| 118 | - url = /url\(['"]?([^\)"']+)/.exec(url); | |
| 119 | - download.href = url[1]; | |
| 120 | - } else if (fontObj.data) { | |
| 121 | - url = URL.createObjectURL(new Blob([fontObj.data], { | |
| 122 | - type: fontObj.mimeType, | |
| 123 | - })); | |
| 124 | - download.href = url; | |
| 123 | + let download; | |
| 124 | + if (!fontObj.css) { | |
| 125 | + download = document.createElement("a"); | |
| 126 | + if (url) { | |
| 127 | + url = /url\(['"]?([^)"']+)/.exec(url); | |
| 128 | + download.href = url[1]; | |
| 129 | + } else if (fontObj.data) { | |
| 130 | + download.href = URL.createObjectURL( | |
| 131 | + new Blob([fontObj.data], { type: fontObj.mimetype }) | |
| 132 | + ); | |
| 133 | + } | |
| 134 | + download.textContent = "Download"; | |
| 125 | 135 | } |
| 126 | - download.textContent = 'Download'; | |
| 127 | - var logIt = document.createElement('a'); | |
| 128 | - logIt.href = ''; | |
| 129 | - logIt.textContent = 'Log'; | |
| 130 | - logIt.addEventListener('click', function(event) { | |
| 136 | + | |
| 137 | + const logIt = document.createElement("a"); | |
| 138 | + logIt.href = ""; | |
| 139 | + logIt.textContent = "Log"; | |
| 140 | + logIt.addEventListener("click", function (event) { | |
| 131 | 141 | event.preventDefault(); |
| 132 | 142 | console.log(fontObj); |
| 133 | 143 | }); |
| 134 | - var select = document.createElement('input'); | |
| 135 | - select.setAttribute('type', 'checkbox'); | |
| 144 | + const select = document.createElement("input"); | |
| 145 | + select.setAttribute("type", "checkbox"); | |
| 136 | 146 | select.dataset.fontName = fontName; |
| 137 | - select.addEventListener('click', (function(select, fontName) { | |
| 138 | - return (function() { | |
| 139 | - selectFont(fontName, select.checked); | |
| 140 | - }); | |
| 141 | - })(select, fontName)); | |
| 142 | - font.appendChild(select); | |
| 143 | - font.appendChild(name); | |
| 144 | - font.appendChild(document.createTextNode(' ')); | |
| 145 | - font.appendChild(download); | |
| 146 | - font.appendChild(document.createTextNode(' ')); | |
| 147 | - font.appendChild(logIt); | |
| 148 | - font.appendChild(moreInfo); | |
| 149 | - fonts.appendChild(font); | |
| 147 | + select.addEventListener("click", function () { | |
| 148 | + selectFont(fontName, select.checked); | |
| 149 | + }); | |
| 150 | + if (download) { | |
| 151 | + font.append(select, name, " ", download, " ", logIt, moreInfo); | |
| 152 | + } else { | |
| 153 | + font.append(select, name, " ", logIt, moreInfo); | |
| 154 | + } | |
| 155 | + fonts.append(font); | |
| 150 | 156 | // Somewhat of a hack, should probably add a hook for when the text layer |
| 151 | 157 | // is done rendering. |
| 152 | 158 | setTimeout(() => { |
| 153 | 159 | if (this.active) { |
| @@ -157,64 +163,55 @@ | ||
| 157 | 163 | }, |
| 158 | 164 | }; |
| 159 | 165 | })(); |
| 160 | 166 | |
| 161 | -var opMap; | |
| 162 | - | |
| 163 | 167 | // Manages all the page steppers. |
| 164 | -var StepperManager = (function StepperManagerClosure() { | |
| 165 | - var steppers = []; | |
| 166 | - var stepperDiv = null; | |
| 167 | - var stepperControls = null; | |
| 168 | - var stepperChooser = null; | |
| 169 | - var breakPoints = Object.create(null); | |
| 168 | +const StepperManager = (function StepperManagerClosure() { | |
| 169 | + let steppers = []; | |
| 170 | + let stepperDiv = null; | |
| 171 | + let stepperControls = null; | |
| 172 | + let stepperChooser = null; | |
| 173 | + let breakPoints = Object.create(null); | |
| 170 | 174 | return { |
| 171 | 175 | // Properties/functions needed by PDFBug. |
| 172 | - id: 'Stepper', | |
| 173 | - name: 'Stepper', | |
| 176 | + id: "Stepper", | |
| 177 | + name: "Stepper", | |
| 174 | 178 | panel: null, |
| 175 | 179 | manager: null, |
| 176 | - init: function init(pdfjsLib) { | |
| 177 | - var self = this; | |
| 178 | - this.panel.setAttribute('style', 'padding: 5px;'); | |
| 179 | - stepperControls = document.createElement('div'); | |
| 180 | - stepperChooser = document.createElement('select'); | |
| 181 | - stepperChooser.addEventListener('change', function(event) { | |
| 180 | + init() { | |
| 181 | + const self = this; | |
| 182 | + stepperControls = document.createElement("div"); | |
| 183 | + stepperChooser = document.createElement("select"); | |
| 184 | + stepperChooser.addEventListener("change", function (event) { | |
| 182 | 185 | self.selectStepper(this.value); |
| 183 | 186 | }); |
| 184 | - stepperControls.appendChild(stepperChooser); | |
| 185 | - stepperDiv = document.createElement('div'); | |
| 186 | - this.panel.appendChild(stepperControls); | |
| 187 | - this.panel.appendChild(stepperDiv); | |
| 188 | - if (sessionStorage.getItem('pdfjsBreakPoints')) { | |
| 189 | - breakPoints = JSON.parse(sessionStorage.getItem('pdfjsBreakPoints')); | |
| 187 | + stepperControls.append(stepperChooser); | |
| 188 | + stepperDiv = document.createElement("div"); | |
| 189 | + this.panel.append(stepperControls, stepperDiv); | |
| 190 | + if (sessionStorage.getItem("pdfjsBreakPoints")) { | |
| 191 | + breakPoints = JSON.parse(sessionStorage.getItem("pdfjsBreakPoints")); | |
| 190 | 192 | } |
| 191 | - | |
| 192 | - opMap = Object.create(null); | |
| 193 | - for (var key in pdfjsLib.OPS) { | |
| 194 | - opMap[pdfjsLib.OPS[key]] = key; | |
| 195 | - } | |
| 196 | 193 | }, |
| 197 | - cleanup: function cleanup() { | |
| 198 | - stepperChooser.textContent = ''; | |
| 199 | - stepperDiv.textContent = ''; | |
| 194 | + cleanup() { | |
| 195 | + stepperChooser.textContent = ""; | |
| 196 | + stepperDiv.textContent = ""; | |
| 200 | 197 | steppers = []; |
| 201 | 198 | }, |
| 202 | 199 | enabled: false, |
| 203 | 200 | active: false, |
| 204 | 201 | // Stepper specific functions. |
| 205 | - create: function create(pageIndex) { | |
| 206 | - var debug = document.createElement('div'); | |
| 207 | - debug.id = 'stepper' + pageIndex; | |
| 208 | - debug.setAttribute('hidden', true); | |
| 209 | - debug.className = 'stepper'; | |
| 210 | - stepperDiv.appendChild(debug); | |
| 211 | - var b = document.createElement('option'); | |
| 212 | - b.textContent = 'Page ' + (pageIndex + 1); | |
| 202 | + create(pageIndex) { | |
| 203 | + const debug = document.createElement("div"); | |
| 204 | + debug.id = "stepper" + pageIndex; | |
| 205 | + debug.hidden = true; | |
| 206 | + debug.className = "stepper"; | |
| 207 | + stepperDiv.append(debug); | |
| 208 | + const b = document.createElement("option"); | |
| 209 | + b.textContent = "Page " + (pageIndex + 1); | |
| 213 | 210 | b.value = pageIndex; |
| 214 | - stepperChooser.appendChild(b); | |
| 215 | - var initBreakPoints = breakPoints[pageIndex] || []; | |
| 216 | - var stepper = new Stepper(debug, pageIndex, initBreakPoints); | |
| 211 | + stepperChooser.append(b); | |
| 212 | + const initBreakPoints = breakPoints[pageIndex] || []; | |
| 213 | + const stepper = new Stepper(debug, pageIndex, initBreakPoints); | |
| 217 | 214 | steppers.push(stepper); |
| 218 | 215 | if (steppers.length === 1) { |
| 219 | 216 | this.selectStepper(pageIndex, false); |
| 220 | 217 | } |
| @@ -219,40 +216,32 @@ | ||
| 219 | 216 | this.selectStepper(pageIndex, false); |
| 220 | 217 | } |
| 221 | 218 | return stepper; |
| 222 | 219 | }, |
| 223 | - selectStepper: function selectStepper(pageIndex, selectPanel) { | |
| 224 | - var i; | |
| 225 | - pageIndex = pageIndex | 0; | |
| 220 | + selectStepper(pageIndex, selectPanel) { | |
| 221 | + pageIndex |= 0; | |
| 226 | 222 | if (selectPanel) { |
| 227 | 223 | this.manager.selectPanel(this); |
| 228 | 224 | } |
| 229 | - for (i = 0; i < steppers.length; ++i) { | |
| 230 | - var stepper = steppers[i]; | |
| 231 | - if (stepper.pageIndex === pageIndex) { | |
| 232 | - stepper.panel.removeAttribute('hidden'); | |
| 233 | - } else { | |
| 234 | - stepper.panel.setAttribute('hidden', true); | |
| 235 | - } | |
| 225 | + for (const stepper of steppers) { | |
| 226 | + stepper.panel.hidden = stepper.pageIndex !== pageIndex; | |
| 236 | 227 | } |
| 237 | - var options = stepperChooser.options; | |
| 238 | - for (i = 0; i < options.length; ++i) { | |
| 239 | - var option = options[i]; | |
| 228 | + for (const option of stepperChooser.options) { | |
| 240 | 229 | option.selected = (option.value | 0) === pageIndex; |
| 241 | 230 | } |
| 242 | 231 | }, |
| 243 | - saveBreakPoints: function saveBreakPoints(pageIndex, bps) { | |
| 232 | + saveBreakPoints(pageIndex, bps) { | |
| 244 | 233 | breakPoints[pageIndex] = bps; |
| 245 | - sessionStorage.setItem('pdfjsBreakPoints', JSON.stringify(breakPoints)); | |
| 234 | + sessionStorage.setItem("pdfjsBreakPoints", JSON.stringify(breakPoints)); | |
| 246 | 235 | }, |
| 247 | 236 | }; |
| 248 | 237 | })(); |
| 249 | 238 | |
| 250 | -// The stepper for each page's IRQueue. | |
| 251 | -var Stepper = (function StepperClosure() { | |
| 239 | +// The stepper for each page's operatorList. | |
| 240 | +class Stepper { | |
| 252 | 241 | // Shorter way to create element and optionally set textContent. |
| 253 | - function c(tag, textContent) { | |
| 254 | - var d = document.createElement(tag); | |
| 242 | + #c(tag, textContent) { | |
| 243 | + const d = document.createElement(tag); | |
| 255 | 244 | if (textContent) { |
| 256 | 245 | d.textContent = textContent; |
| 257 | 246 | } |
| 258 | 247 | return d; |
| @@ -257,36 +246,39 @@ | ||
| 257 | 246 | } |
| 258 | 247 | return d; |
| 259 | 248 | } |
| 260 | 249 | |
| 261 | - function simplifyArgs(args) { | |
| 262 | - if (typeof args === 'string') { | |
| 263 | - var MAX_STRING_LENGTH = 75; | |
| 264 | - return args.length <= MAX_STRING_LENGTH ? args : | |
| 265 | - args.substr(0, MAX_STRING_LENGTH) + '...'; | |
| 250 | + #simplifyArgs(args) { | |
| 251 | + if (typeof args === "string") { | |
| 252 | + const MAX_STRING_LENGTH = 75; | |
| 253 | + return args.length <= MAX_STRING_LENGTH | |
| 254 | + ? args | |
| 255 | + : args.substring(0, MAX_STRING_LENGTH) + "..."; | |
| 266 | 256 | } |
| 267 | - if (typeof args !== 'object' || args === null) { | |
| 257 | + if (typeof args !== "object" || args === null) { | |
| 268 | 258 | return args; |
| 269 | 259 | } |
| 270 | - if ('length' in args) { // array | |
| 271 | - var simpleArgs = [], i, ii; | |
| 272 | - var MAX_ITEMS = 10; | |
| 260 | + if ("length" in args) { | |
| 261 | + // array | |
| 262 | + const MAX_ITEMS = 10, | |
| 263 | + simpleArgs = []; | |
| 264 | + let i, ii; | |
| 273 | 265 | for (i = 0, ii = Math.min(MAX_ITEMS, args.length); i < ii; i++) { |
| 274 | - simpleArgs.push(simplifyArgs(args[i])); | |
| 266 | + simpleArgs.push(this.#simplifyArgs(args[i])); | |
| 275 | 267 | } |
| 276 | 268 | if (i < args.length) { |
| 277 | - simpleArgs.push('...'); | |
| 269 | + simpleArgs.push("..."); | |
| 278 | 270 | } |
| 279 | 271 | return simpleArgs; |
| 280 | 272 | } |
| 281 | - var simpleObj = {}; | |
| 282 | - for (var key in args) { | |
| 283 | - simpleObj[key] = simplifyArgs(args[key]); | |
| 273 | + const simpleObj = {}; | |
| 274 | + for (const key in args) { | |
| 275 | + simpleObj[key] = this.#simplifyArgs(args[key]); | |
| 284 | 276 | } |
| 285 | 277 | return simpleObj; |
| 286 | 278 | } |
| 287 | 279 | |
| 288 | - function Stepper(panel, pageIndex, initialBreakPoints) { | |
| 280 | + constructor(panel, pageIndex, initialBreakPoints) { | |
| 289 | 281 | this.panel = panel; |
| 290 | 282 | this.breakPoint = 0; |
| 291 | 283 | this.nextBreakPoint = null; |
| 292 | 284 | this.pageIndex = pageIndex; |
| @@ -292,163 +284,183 @@ | ||
| 292 | 284 | this.pageIndex = pageIndex; |
| 293 | 285 | this.breakPoints = initialBreakPoints; |
| 294 | 286 | this.currentIdx = -1; |
| 295 | 287 | this.operatorListIdx = 0; |
| 288 | + this.indentLevel = 0; | |
| 296 | 289 | } |
| 297 | - Stepper.prototype = { | |
| 298 | - init: function init(operatorList) { | |
| 299 | - var panel = this.panel; | |
| 300 | - var content = c('div', 'c=continue, s=step'); | |
| 301 | - var table = c('table'); | |
| 302 | - content.appendChild(table); | |
| 303 | - table.cellSpacing = 0; | |
| 304 | - var headerRow = c('tr'); | |
| 305 | - table.appendChild(headerRow); | |
| 306 | - headerRow.appendChild(c('th', 'Break')); | |
| 307 | - headerRow.appendChild(c('th', 'Idx')); | |
| 308 | - headerRow.appendChild(c('th', 'fn')); | |
| 309 | - headerRow.appendChild(c('th', 'args')); | |
| 310 | - panel.appendChild(content); | |
| 311 | - this.table = table; | |
| 312 | - this.updateOperatorList(operatorList); | |
| 313 | - }, | |
| 314 | - updateOperatorList: function updateOperatorList(operatorList) { | |
| 315 | - var self = this; | |
| 316 | 290 | |
| 317 | - function cboxOnClick() { | |
| 318 | - var x = +this.dataset.idx; | |
| 319 | - if (this.checked) { | |
| 320 | - self.breakPoints.push(x); | |
| 321 | - } else { | |
| 322 | - self.breakPoints.splice(self.breakPoints.indexOf(x), 1); | |
| 323 | - } | |
| 324 | - StepperManager.saveBreakPoints(self.pageIndex, self.breakPoints); | |
| 291 | + init(operatorList) { | |
| 292 | + const panel = this.panel; | |
| 293 | + const content = this.#c("div", "c=continue, s=step"); | |
| 294 | + const table = this.#c("table"); | |
| 295 | + content.append(table); | |
| 296 | + table.cellSpacing = 0; | |
| 297 | + const headerRow = this.#c("tr"); | |
| 298 | + table.append(headerRow); | |
| 299 | + headerRow.append( | |
| 300 | + this.#c("th", "Break"), | |
| 301 | + this.#c("th", "Idx"), | |
| 302 | + this.#c("th", "fn"), | |
| 303 | + this.#c("th", "args") | |
| 304 | + ); | |
| 305 | + panel.append(content); | |
| 306 | + this.table = table; | |
| 307 | + this.updateOperatorList(operatorList); | |
| 308 | + } | |
| 309 | + | |
| 310 | + updateOperatorList(operatorList) { | |
| 311 | + const self = this; | |
| 312 | + | |
| 313 | + function cboxOnClick() { | |
| 314 | + const x = +this.dataset.idx; | |
| 315 | + if (this.checked) { | |
| 316 | + self.breakPoints.push(x); | |
| 317 | + } else { | |
| 318 | + self.breakPoints.splice(self.breakPoints.indexOf(x), 1); | |
| 325 | 319 | } |
| 320 | + StepperManager.saveBreakPoints(self.pageIndex, self.breakPoints); | |
| 321 | + } | |
| 326 | 322 | |
| 327 | - var MAX_OPERATORS_COUNT = 15000; | |
| 328 | - if (this.operatorListIdx > MAX_OPERATORS_COUNT) { | |
| 329 | - return; | |
| 330 | - } | |
| 323 | + const MAX_OPERATORS_COUNT = 15000; | |
| 324 | + if (this.operatorListIdx > MAX_OPERATORS_COUNT) { | |
| 325 | + return; | |
| 326 | + } | |
| 331 | 327 | |
| 332 | - var chunk = document.createDocumentFragment(); | |
| 333 | - var operatorsToDisplay = Math.min(MAX_OPERATORS_COUNT, | |
| 334 | - operatorList.fnArray.length); | |
| 335 | - for (var i = this.operatorListIdx; i < operatorsToDisplay; i++) { | |
| 336 | - var line = c('tr'); | |
| 337 | - line.className = 'line'; | |
| 338 | - line.dataset.idx = i; | |
| 339 | - chunk.appendChild(line); | |
| 340 | - var checked = this.breakPoints.indexOf(i) !== -1; | |
| 341 | - var args = operatorList.argsArray[i] || []; | |
| 328 | + const chunk = document.createDocumentFragment(); | |
| 329 | + const operatorsToDisplay = Math.min( | |
| 330 | + MAX_OPERATORS_COUNT, | |
| 331 | + operatorList.fnArray.length | |
| 332 | + ); | |
| 333 | + for (let i = this.operatorListIdx; i < operatorsToDisplay; i++) { | |
| 334 | + const line = this.#c("tr"); | |
| 335 | + line.className = "line"; | |
| 336 | + line.dataset.idx = i; | |
| 337 | + chunk.append(line); | |
| 338 | + const checked = this.breakPoints.includes(i); | |
| 339 | + const args = operatorList.argsArray[i] || []; | |
| 342 | 340 | |
| 343 | - var breakCell = c('td'); | |
| 344 | - var cbox = c('input'); | |
| 345 | - cbox.type = 'checkbox'; | |
| 346 | - cbox.className = 'points'; | |
| 347 | - cbox.checked = checked; | |
| 348 | - cbox.dataset.idx = i; | |
| 349 | - cbox.onclick = cboxOnClick; | |
| 341 | + const breakCell = this.#c("td"); | |
| 342 | + const cbox = this.#c("input"); | |
| 343 | + cbox.type = "checkbox"; | |
| 344 | + cbox.className = "points"; | |
| 345 | + cbox.checked = checked; | |
| 346 | + cbox.dataset.idx = i; | |
| 347 | + cbox.onclick = cboxOnClick; | |
| 350 | 348 | |
| 351 | - breakCell.appendChild(cbox); | |
| 352 | - line.appendChild(breakCell); | |
| 353 | - line.appendChild(c('td', i.toString())); | |
| 354 | - var fn = opMap[operatorList.fnArray[i]]; | |
| 355 | - var decArgs = args; | |
| 356 | - if (fn === 'showText') { | |
| 357 | - var glyphs = args[0]; | |
| 358 | - var newArgs = []; | |
| 359 | - var str = []; | |
| 360 | - for (var j = 0; j < glyphs.length; j++) { | |
| 361 | - var glyph = glyphs[j]; | |
| 362 | - if (typeof glyph === 'object' && glyph !== null) { | |
| 363 | - str.push(glyph.fontChar); | |
| 364 | - } else { | |
| 365 | - if (str.length > 0) { | |
| 366 | - newArgs.push(str.join('')); | |
| 367 | - str = []; | |
| 368 | - } | |
| 369 | - newArgs.push(glyph); // null or number | |
| 370 | - } | |
| 349 | + breakCell.append(cbox); | |
| 350 | + line.append(breakCell, this.#c("td", i.toString())); | |
| 351 | + const fn = opMap[operatorList.fnArray[i]]; | |
| 352 | + let decArgs = args; | |
| 353 | + if (fn === "showText") { | |
| 354 | + const glyphs = args[0]; | |
| 355 | + const charCodeRow = this.#c("tr"); | |
| 356 | + const fontCharRow = this.#c("tr"); | |
| 357 | + const unicodeRow = this.#c("tr"); | |
| 358 | + for (const glyph of glyphs) { | |
| 359 | + if (typeof glyph === "object" && glyph !== null) { | |
| 360 | + charCodeRow.append(this.#c("td", glyph.originalCharCode)); | |
| 361 | + fontCharRow.append(this.#c("td", glyph.fontChar)); | |
| 362 | + unicodeRow.append(this.#c("td", glyph.unicode)); | |
| 363 | + } else { | |
| 364 | + // null or number | |
| 365 | + const advanceEl = this.#c("td", glyph); | |
| 366 | + advanceEl.classList.add("advance"); | |
| 367 | + charCodeRow.append(advanceEl); | |
| 368 | + fontCharRow.append(this.#c("td")); | |
| 369 | + unicodeRow.append(this.#c("td")); | |
| 371 | 370 | } |
| 372 | - if (str.length > 0) { | |
| 373 | - newArgs.push(str.join('')); | |
| 374 | - } | |
| 375 | - decArgs = [newArgs]; | |
| 376 | 371 | } |
| 377 | - line.appendChild(c('td', fn)); | |
| 378 | - line.appendChild(c('td', JSON.stringify(simplifyArgs(decArgs)))); | |
| 372 | + decArgs = this.#c("td"); | |
| 373 | + const table = this.#c("table"); | |
| 374 | + table.classList.add("showText"); | |
| 375 | + decArgs.append(table); | |
| 376 | + table.append(charCodeRow, fontCharRow, unicodeRow); | |
| 377 | + } else if (fn === "constructPath") { | |
| 378 | + const [op, [path], minMax] = args; | |
| 379 | + decArgs = this.#c("td"); | |
| 380 | + decArgs.append(JSON.stringify(this.#simplifyArgs(path))); | |
| 381 | + decArgs.append(this.#c("br")); | |
| 382 | + decArgs.append(`minMax: ${JSON.stringify(this.#simplifyArgs(minMax))}`); | |
| 383 | + decArgs.append(this.#c("br")); | |
| 384 | + decArgs.append(`→ ${opMap[op]}`); | |
| 385 | + } else if (fn === "restore" && this.indentLevel > 0) { | |
| 386 | + this.indentLevel--; | |
| 379 | 387 | } |
| 380 | - if (operatorsToDisplay < operatorList.fnArray.length) { | |
| 381 | - line = c('tr'); | |
| 382 | - var lastCell = c('td', '...'); | |
| 383 | - lastCell.colspan = 4; | |
| 384 | - chunk.appendChild(lastCell); | |
| 388 | + line.append(this.#c("td", " ".repeat(this.indentLevel * 2) + fn)); | |
| 389 | + if (fn === "save") { | |
| 390 | + this.indentLevel++; | |
| 385 | 391 | } |
| 386 | - this.operatorListIdx = operatorList.fnArray.length; | |
| 387 | - this.table.appendChild(chunk); | |
| 388 | - }, | |
| 389 | - getNextBreakPoint: function getNextBreakPoint() { | |
| 390 | - this.breakPoints.sort(function(a, b) { | |
| 391 | - return a - b; | |
| 392 | - }); | |
| 393 | - for (var i = 0; i < this.breakPoints.length; i++) { | |
| 394 | - if (this.breakPoints[i] > this.currentIdx) { | |
| 395 | - return this.breakPoints[i]; | |
| 396 | - } | |
| 392 | + | |
| 393 | + if (decArgs instanceof HTMLElement) { | |
| 394 | + line.append(decArgs); | |
| 395 | + } else { | |
| 396 | + line.append(this.#c("td", JSON.stringify(this.#simplifyArgs(decArgs)))); | |
| 397 | 397 | } |
| 398 | - return null; | |
| 399 | - }, | |
| 400 | - breakIt: function breakIt(idx, callback) { | |
| 401 | - StepperManager.selectStepper(this.pageIndex, true); | |
| 402 | - var self = this; | |
| 403 | - var dom = document; | |
| 404 | - self.currentIdx = idx; | |
| 405 | - var listener = function(e) { | |
| 406 | - switch (e.keyCode) { | |
| 407 | - case 83: // step | |
| 408 | - dom.removeEventListener('keydown', listener); | |
| 409 | - self.nextBreakPoint = self.currentIdx + 1; | |
| 410 | - self.goTo(-1); | |
| 411 | - callback(); | |
| 412 | - break; | |
| 413 | - case 67: // continue | |
| 414 | - dom.removeEventListener('keydown', listener); | |
| 415 | - var breakPoint = self.getNextBreakPoint(); | |
| 416 | - self.nextBreakPoint = breakPoint; | |
| 417 | - self.goTo(-1); | |
| 418 | - callback(); | |
| 419 | - break; | |
| 420 | - } | |
| 421 | - }; | |
| 422 | - dom.addEventListener('keydown', listener); | |
| 423 | - self.goTo(idx); | |
| 424 | - }, | |
| 425 | - goTo: function goTo(idx) { | |
| 426 | - var allRows = this.panel.getElementsByClassName('line'); | |
| 427 | - for (var x = 0, xx = allRows.length; x < xx; ++x) { | |
| 428 | - var row = allRows[x]; | |
| 429 | - if ((row.dataset.idx | 0) === idx) { | |
| 430 | - row.style.backgroundColor = 'rgb(251,250,207)'; | |
| 431 | - row.scrollIntoView(); | |
| 432 | - } else { | |
| 433 | - row.style.backgroundColor = null; | |
| 434 | - } | |
| 398 | + } | |
| 399 | + if (operatorsToDisplay < operatorList.fnArray.length) { | |
| 400 | + const lastCell = this.#c("td", "..."); | |
| 401 | + lastCell.colspan = 4; | |
| 402 | + chunk.append(lastCell); | |
| 403 | + } | |
| 404 | + this.operatorListIdx = operatorList.fnArray.length; | |
| 405 | + this.table.append(chunk); | |
| 406 | + } | |
| 407 | + | |
| 408 | + getNextBreakPoint() { | |
| 409 | + this.breakPoints.sort((a, b) => a - b); | |
| 410 | + for (const breakPoint of this.breakPoints) { | |
| 411 | + if (breakPoint > this.currentIdx) { | |
| 412 | + return breakPoint; | |
| 435 | 413 | } |
| 436 | - }, | |
| 437 | - }; | |
| 438 | - return Stepper; | |
| 439 | -})(); | |
| 414 | + } | |
| 415 | + return null; | |
| 416 | + } | |
| 440 | 417 | |
| 441 | -var Stats = (function Stats() { | |
| 442 | - var stats = []; | |
| 418 | + breakIt(idx, callback) { | |
| 419 | + StepperManager.selectStepper(this.pageIndex, true); | |
| 420 | + this.currentIdx = idx; | |
| 421 | + | |
| 422 | + const listener = evt => { | |
| 423 | + switch (evt.keyCode) { | |
| 424 | + case 83: // step | |
| 425 | + document.removeEventListener("keydown", listener); | |
| 426 | + this.nextBreakPoint = this.currentIdx + 1; | |
| 427 | + this.goTo(-1); | |
| 428 | + callback(); | |
| 429 | + break; | |
| 430 | + case 67: // continue | |
| 431 | + document.removeEventListener("keydown", listener); | |
| 432 | + this.nextBreakPoint = this.getNextBreakPoint(); | |
| 433 | + this.goTo(-1); | |
| 434 | + callback(); | |
| 435 | + break; | |
| 436 | + } | |
| 437 | + }; | |
| 438 | + document.addEventListener("keydown", listener); | |
| 439 | + this.goTo(idx); | |
| 440 | + } | |
| 441 | + | |
| 442 | + goTo(idx) { | |
| 443 | + const allRows = this.panel.getElementsByClassName("line"); | |
| 444 | + for (const row of allRows) { | |
| 445 | + if ((row.dataset.idx | 0) === idx) { | |
| 446 | + row.style.backgroundColor = "rgb(251,250,207)"; | |
| 447 | + row.scrollIntoView(); | |
| 448 | + } else { | |
| 449 | + row.style.backgroundColor = null; | |
| 450 | + } | |
| 451 | + } | |
| 452 | + } | |
| 453 | +} | |
| 454 | + | |
| 455 | +const Stats = (function Stats() { | |
| 456 | + let stats = []; | |
| 443 | 457 | function clear(node) { |
| 444 | - while (node.hasChildNodes()) { | |
| 445 | - node.removeChild(node.lastChild); | |
| 446 | - } | |
| 458 | + node.textContent = ""; // Remove any `node` contents from the DOM. | |
| 447 | 459 | } |
| 448 | 460 | function getStatIndex(pageNumber) { |
| 449 | - for (var i = 0, ii = stats.length; i < ii; ++i) { | |
| 450 | - if (stats[i].pageNumber === pageNumber) { | |
| 461 | + for (const [i, stat] of stats.entries()) { | |
| 462 | + if (stat.pageNumber === pageNumber) { | |
| 451 | 463 | return i; |
| 452 | 464 | } |
| 453 | 465 | } |
| 454 | 466 | return false; |
| @@ -454,16 +466,13 @@ | ||
| 454 | 466 | return false; |
| 455 | 467 | } |
| 456 | 468 | return { |
| 457 | 469 | // Properties/functions needed by PDFBug. |
| 458 | - id: 'Stats', | |
| 459 | - name: 'Stats', | |
| 470 | + id: "Stats", | |
| 471 | + name: "Stats", | |
| 460 | 472 | panel: null, |
| 461 | 473 | manager: null, |
| 462 | - init(pdfjsLib) { | |
| 463 | - this.panel.setAttribute('style', 'padding: 5px;'); | |
| 464 | - pdfjsLib.PDFJS.enableStats = true; | |
| 465 | - }, | |
| 474 | + init() {}, | |
| 466 | 475 | enabled: false, |
| 467 | 476 | active: false, |
| 468 | 477 | // Stats specific functions. |
| 469 | 478 | add(pageNumber, stat) { |
| @@ -469,30 +478,26 @@ | ||
| 469 | 478 | add(pageNumber, stat) { |
| 470 | 479 | if (!stat) { |
| 471 | 480 | return; |
| 472 | 481 | } |
| 473 | - var statsIndex = getStatIndex(pageNumber); | |
| 482 | + const statsIndex = getStatIndex(pageNumber); | |
| 474 | 483 | if (statsIndex !== false) { |
| 475 | - var b = stats[statsIndex]; | |
| 476 | - this.panel.removeChild(b.div); | |
| 484 | + stats[statsIndex].div.remove(); | |
| 477 | 485 | stats.splice(statsIndex, 1); |
| 478 | 486 | } |
| 479 | - var wrapper = document.createElement('div'); | |
| 480 | - wrapper.className = 'stats'; | |
| 481 | - var title = document.createElement('div'); | |
| 482 | - title.className = 'title'; | |
| 483 | - title.textContent = 'Page: ' + pageNumber; | |
| 484 | - var statsDiv = document.createElement('div'); | |
| 487 | + const wrapper = document.createElement("div"); | |
| 488 | + wrapper.className = "stats"; | |
| 489 | + const title = document.createElement("div"); | |
| 490 | + title.className = "title"; | |
| 491 | + title.textContent = "Page: " + pageNumber; | |
| 492 | + const statsDiv = document.createElement("div"); | |
| 485 | 493 | statsDiv.textContent = stat.toString(); |
| 486 | - wrapper.appendChild(title); | |
| 487 | - wrapper.appendChild(statsDiv); | |
| 488 | - stats.push({ pageNumber, div: wrapper, }); | |
| 489 | - stats.sort(function(a, b) { | |
| 490 | - return a.pageNumber - b.pageNumber; | |
| 491 | - }); | |
| 494 | + wrapper.append(title, statsDiv); | |
| 495 | + stats.push({ pageNumber, div: wrapper }); | |
| 496 | + stats.sort((a, b) => a.pageNumber - b.pageNumber); | |
| 492 | 497 | clear(this.panel); |
| 493 | - for (var i = 0, ii = stats.length; i < ii; ++i) { | |
| 494 | - this.panel.appendChild(stats[i].div); | |
| 498 | + for (const entry of stats) { | |
| 499 | + this.panel.append(entry.div); | |
| 495 | 500 | } |
| 496 | 501 | }, |
| 497 | 502 | cleanup() { |
| 498 | 503 | stats = []; |
| @@ -501,120 +506,122 @@ | ||
| 501 | 506 | }; |
| 502 | 507 | })(); |
| 503 | 508 | |
| 504 | 509 | // Manages all the debugging tools. |
| 505 | -window.PDFBug = (function PDFBugClosure() { | |
| 506 | - var panelWidth = 300; | |
| 507 | - var buttons = []; | |
| 508 | - var activePanel = null; | |
| 510 | +class PDFBug { | |
| 511 | + static #buttons = []; | |
| 509 | 512 | |
| 510 | - return { | |
| 511 | - tools: [ | |
| 512 | - FontInspector, | |
| 513 | - StepperManager, | |
| 514 | - Stats | |
| 515 | - ], | |
| 516 | - enable(ids) { | |
| 517 | - var all = false, tools = this.tools; | |
| 518 | - if (ids.length === 1 && ids[0] === 'all') { | |
| 519 | - all = true; | |
| 513 | + static #activePanel = null; | |
| 514 | + | |
| 515 | + static tools = [FontInspector, StepperManager, Stats]; | |
| 516 | + | |
| 517 | + static enable(ids) { | |
| 518 | + const all = ids.length === 1 && ids[0] === "all"; | |
| 519 | + const tools = this.tools; | |
| 520 | + for (const tool of tools) { | |
| 521 | + if (all || ids.includes(tool.id)) { | |
| 522 | + tool.enabled = true; | |
| 520 | 523 | } |
| 521 | - for (var i = 0; i < tools.length; ++i) { | |
| 522 | - var tool = tools[i]; | |
| 523 | - if (all || ids.indexOf(tool.id) !== -1) { | |
| 524 | - tool.enabled = true; | |
| 525 | - } | |
| 524 | + } | |
| 525 | + if (!all) { | |
| 526 | + // Sort the tools by the order they are enabled. | |
| 527 | + tools.sort(function (a, b) { | |
| 528 | + let indexA = ids.indexOf(a.id); | |
| 529 | + indexA = indexA < 0 ? tools.length : indexA; | |
| 530 | + let indexB = ids.indexOf(b.id); | |
| 531 | + indexB = indexB < 0 ? tools.length : indexB; | |
| 532 | + return indexA - indexB; | |
| 533 | + }); | |
| 534 | + } | |
| 535 | + } | |
| 536 | + | |
| 537 | + static init(container, ids) { | |
| 538 | + this.loadCSS(); | |
| 539 | + this.enable(ids); | |
| 540 | + /* | |
| 541 | + * Basic Layout: | |
| 542 | + * PDFBug | |
| 543 | + * Controls | |
| 544 | + * Panels | |
| 545 | + * Panel | |
| 546 | + * Panel | |
| 547 | + * ... | |
| 548 | + */ | |
| 549 | + const ui = document.createElement("div"); | |
| 550 | + ui.id = "PDFBug"; | |
| 551 | + | |
| 552 | + const controls = document.createElement("div"); | |
| 553 | + controls.setAttribute("class", "controls"); | |
| 554 | + ui.append(controls); | |
| 555 | + | |
| 556 | + const panels = document.createElement("div"); | |
| 557 | + panels.setAttribute("class", "panels"); | |
| 558 | + ui.append(panels); | |
| 559 | + | |
| 560 | + container.append(ui); | |
| 561 | + container.style.right = "var(--panel-width)"; | |
| 562 | + | |
| 563 | + // Initialize all the debugging tools. | |
| 564 | + for (const tool of this.tools) { | |
| 565 | + const panel = document.createElement("div"); | |
| 566 | + const panelButton = document.createElement("button"); | |
| 567 | + panelButton.textContent = tool.name; | |
| 568 | + panelButton.addEventListener("click", event => { | |
| 569 | + event.preventDefault(); | |
| 570 | + this.selectPanel(tool); | |
| 571 | + }); | |
| 572 | + controls.append(panelButton); | |
| 573 | + panels.append(panel); | |
| 574 | + tool.panel = panel; | |
| 575 | + tool.manager = this; | |
| 576 | + if (tool.enabled) { | |
| 577 | + tool.init(); | |
| 578 | + } else { | |
| 579 | + panel.textContent = | |
| 580 | + `${tool.name} is disabled. To enable add "${tool.id}" to ` + | |
| 581 | + "the pdfBug parameter and refresh (separate multiple by commas)."; | |
| 526 | 582 | } |
| 527 | - if (!all) { | |
| 528 | - // Sort the tools by the order they are enabled. | |
| 529 | - tools.sort(function(a, b) { | |
| 530 | - var indexA = ids.indexOf(a.id); | |
| 531 | - indexA = indexA < 0 ? tools.length : indexA; | |
| 532 | - var indexB = ids.indexOf(b.id); | |
| 533 | - indexB = indexB < 0 ? tools.length : indexB; | |
| 534 | - return indexA - indexB; | |
| 535 | - }); | |
| 536 | - } | |
| 537 | - }, | |
| 538 | - init(pdfjsLib, container) { | |
| 539 | - /* | |
| 540 | - * Basic Layout: | |
| 541 | - * PDFBug | |
| 542 | - * Controls | |
| 543 | - * Panels | |
| 544 | - * Panel | |
| 545 | - * Panel | |
| 546 | - * ... | |
| 547 | - */ | |
| 548 | - var ui = document.createElement('div'); | |
| 549 | - ui.id = 'PDFBug'; | |
| 583 | + this.#buttons.push(panelButton); | |
| 584 | + } | |
| 585 | + this.selectPanel(0); | |
| 586 | + } | |
| 550 | 587 | |
| 551 | - var controls = document.createElement('div'); | |
| 552 | - controls.setAttribute('class', 'controls'); | |
| 553 | - ui.appendChild(controls); | |
| 588 | + static loadCSS() { | |
| 589 | + const { url } = import.meta; | |
| 554 | 590 | |
| 555 | - var panels = document.createElement('div'); | |
| 556 | - panels.setAttribute('class', 'panels'); | |
| 557 | - ui.appendChild(panels); | |
| 591 | + const link = document.createElement("link"); | |
| 592 | + link.rel = "stylesheet"; | |
| 593 | + link.href = url.replace(/\.js$/, ".css"); | |
| 558 | 594 | |
| 559 | - container.appendChild(ui); | |
| 560 | - container.style.right = panelWidth + 'px'; | |
| 595 | + document.head.append(link); | |
| 596 | + } | |
| 561 | 597 | |
| 562 | - // Initialize all the debugging tools. | |
| 563 | - var tools = this.tools; | |
| 564 | - var self = this; | |
| 565 | - for (var i = 0; i < tools.length; ++i) { | |
| 566 | - var tool = tools[i]; | |
| 567 | - var panel = document.createElement('div'); | |
| 568 | - var panelButton = document.createElement('button'); | |
| 569 | - panelButton.textContent = tool.name; | |
| 570 | - panelButton.addEventListener('click', (function(selected) { | |
| 571 | - return function(event) { | |
| 572 | - event.preventDefault(); | |
| 573 | - self.selectPanel(selected); | |
| 574 | - }; | |
| 575 | - })(i)); | |
| 576 | - controls.appendChild(panelButton); | |
| 577 | - panels.appendChild(panel); | |
| 578 | - tool.panel = panel; | |
| 579 | - tool.manager = this; | |
| 580 | - if (tool.enabled) { | |
| 581 | - tool.init(pdfjsLib); | |
| 582 | - } else { | |
| 583 | - panel.textContent = tool.name + ' is disabled. To enable add ' + | |
| 584 | - ' "' + tool.id + '" to the pdfBug parameter ' + | |
| 585 | - 'and refresh (separate multiple by commas).'; | |
| 586 | - } | |
| 587 | - buttons.push(panelButton); | |
| 598 | + static cleanup() { | |
| 599 | + for (const tool of this.tools) { | |
| 600 | + if (tool.enabled) { | |
| 601 | + tool.cleanup(); | |
| 588 | 602 | } |
| 589 | - this.selectPanel(0); | |
| 590 | - }, | |
| 591 | - cleanup() { | |
| 592 | - for (var i = 0, ii = this.tools.length; i < ii; i++) { | |
| 593 | - if (this.tools[i].enabled) { | |
| 594 | - this.tools[i].cleanup(); | |
| 595 | - } | |
| 596 | - } | |
| 597 | - }, | |
| 598 | - selectPanel(index) { | |
| 599 | - if (typeof index !== 'number') { | |
| 600 | - index = this.tools.indexOf(index); | |
| 601 | - } | |
| 602 | - if (index === activePanel) { | |
| 603 | - return; | |
| 604 | - } | |
| 605 | - activePanel = index; | |
| 606 | - var tools = this.tools; | |
| 607 | - for (var j = 0; j < tools.length; ++j) { | |
| 608 | - if (j === index) { | |
| 609 | - buttons[j].setAttribute('class', 'active'); | |
| 610 | - tools[j].active = true; | |
| 611 | - tools[j].panel.removeAttribute('hidden'); | |
| 612 | - } else { | |
| 613 | - buttons[j].setAttribute('class', ''); | |
| 614 | - tools[j].active = false; | |
| 615 | - tools[j].panel.setAttribute('hidden', 'true'); | |
| 616 | - } | |
| 617 | - } | |
| 618 | - }, | |
| 619 | - }; | |
| 620 | -})(); | |
| 603 | + } | |
| 604 | + } | |
| 605 | + | |
| 606 | + static selectPanel(index) { | |
| 607 | + if (typeof index !== "number") { | |
| 608 | + index = this.tools.indexOf(index); | |
| 609 | + } | |
| 610 | + if (index === this.#activePanel) { | |
| 611 | + return; | |
| 612 | + } | |
| 613 | + this.#activePanel = index; | |
| 614 | + for (const [j, tool] of this.tools.entries()) { | |
| 615 | + const isActive = j === index; | |
| 616 | + this.#buttons[j].classList.toggle("active", isActive); | |
| 617 | + tool.active = isActive; | |
| 618 | + tool.panel.hidden = !isActive; | |
| 619 | + } | |
| 620 | + } | |
| 621 | +} | |
| 622 | + | |
| 623 | +globalThis.FontInspector = FontInspector; | |
| 624 | +globalThis.StepperManager = StepperManager; | |
| 625 | +globalThis.Stats = Stats; | |
| 626 | + | |
| 627 | +export { PDFBug }; | |