Merge pull request #16961 from Snuffleupagus/debugger-rm-closure
Remove (some) closures from `web/debugger.js`
This commit is contained in:
		
						commit
						518590ac7d
					
				@ -13,6 +13,10 @@
 | 
				
			|||||||
 * limitations under the License.
 | 
					 * limitations under the License.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:root {
 | 
				
			||||||
 | 
					  --panel-width: 300px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#PDFBug,
 | 
					#PDFBug,
 | 
				
			||||||
#PDFBug :is(input, button, select) {
 | 
					#PDFBug :is(input, button, select) {
 | 
				
			||||||
  font: message-box;
 | 
					  font: message-box;
 | 
				
			||||||
@ -26,7 +30,7 @@
 | 
				
			|||||||
  bottom: 0;
 | 
					  bottom: 0;
 | 
				
			||||||
  font-size: 10px;
 | 
					  font-size: 10px;
 | 
				
			||||||
  padding: 0;
 | 
					  padding: 0;
 | 
				
			||||||
  width: 300px;
 | 
					  width: var(--panel-width);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#PDFBug .controls {
 | 
					#PDFBug .controls {
 | 
				
			||||||
  background: rgba(238, 238, 238, 1);
 | 
					  background: rgba(238, 238, 238, 1);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										517
									
								
								web/debugger.js
									
									
									
									
									
								
							
							
						
						
									
										517
									
								
								web/debugger.js
									
									
									
									
									
								
							@ -225,9 +225,9 @@ const StepperManager = (function StepperManagerClosure() {
 | 
				
			|||||||
})();
 | 
					})();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The stepper for each page's operatorList.
 | 
					// The stepper for each page's operatorList.
 | 
				
			||||||
const Stepper = (function StepperClosure() {
 | 
					class Stepper {
 | 
				
			||||||
  // Shorter way to create element and optionally set textContent.
 | 
					  // Shorter way to create element and optionally set textContent.
 | 
				
			||||||
  function c(tag, textContent) {
 | 
					  #c(tag, textContent) {
 | 
				
			||||||
    const d = document.createElement(tag);
 | 
					    const d = document.createElement(tag);
 | 
				
			||||||
    if (textContent) {
 | 
					    if (textContent) {
 | 
				
			||||||
      d.textContent = textContent;
 | 
					      d.textContent = textContent;
 | 
				
			||||||
@ -235,7 +235,7 @@ const Stepper = (function StepperClosure() {
 | 
				
			|||||||
    return d;
 | 
					    return d;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function simplifyArgs(args) {
 | 
					  #simplifyArgs(args) {
 | 
				
			||||||
    if (typeof args === "string") {
 | 
					    if (typeof args === "string") {
 | 
				
			||||||
      const MAX_STRING_LENGTH = 75;
 | 
					      const MAX_STRING_LENGTH = 75;
 | 
				
			||||||
      return args.length <= MAX_STRING_LENGTH
 | 
					      return args.length <= MAX_STRING_LENGTH
 | 
				
			||||||
@ -251,7 +251,7 @@ const Stepper = (function StepperClosure() {
 | 
				
			|||||||
        simpleArgs = [];
 | 
					        simpleArgs = [];
 | 
				
			||||||
      let i, ii;
 | 
					      let i, ii;
 | 
				
			||||||
      for (i = 0, ii = Math.min(MAX_ITEMS, args.length); i < ii; i++) {
 | 
					      for (i = 0, ii = Math.min(MAX_ITEMS, args.length); i < ii; i++) {
 | 
				
			||||||
        simpleArgs.push(simplifyArgs(args[i]));
 | 
					        simpleArgs.push(this.#simplifyArgs(args[i]));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (i < args.length) {
 | 
					      if (i < args.length) {
 | 
				
			||||||
        simpleArgs.push("...");
 | 
					        simpleArgs.push("...");
 | 
				
			||||||
@ -260,183 +260,179 @@ const Stepper = (function StepperClosure() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    const simpleObj = {};
 | 
					    const simpleObj = {};
 | 
				
			||||||
    for (const key in args) {
 | 
					    for (const key in args) {
 | 
				
			||||||
      simpleObj[key] = simplifyArgs(args[key]);
 | 
					      simpleObj[key] = this.#simplifyArgs(args[key]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return simpleObj;
 | 
					    return simpleObj;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // eslint-disable-next-line no-shadow
 | 
					  constructor(panel, pageIndex, initialBreakPoints) {
 | 
				
			||||||
  class Stepper {
 | 
					    this.panel = panel;
 | 
				
			||||||
    constructor(panel, pageIndex, initialBreakPoints) {
 | 
					    this.breakPoint = 0;
 | 
				
			||||||
      this.panel = panel;
 | 
					    this.nextBreakPoint = null;
 | 
				
			||||||
      this.breakPoint = 0;
 | 
					    this.pageIndex = pageIndex;
 | 
				
			||||||
      this.nextBreakPoint = null;
 | 
					    this.breakPoints = initialBreakPoints;
 | 
				
			||||||
      this.pageIndex = pageIndex;
 | 
					    this.currentIdx = -1;
 | 
				
			||||||
      this.breakPoints = initialBreakPoints;
 | 
					    this.operatorListIdx = 0;
 | 
				
			||||||
      this.currentIdx = -1;
 | 
					    this.indentLevel = 0;
 | 
				
			||||||
      this.operatorListIdx = 0;
 | 
					  }
 | 
				
			||||||
      this.indentLevel = 0;
 | 
					
 | 
				
			||||||
 | 
					  init(operatorList) {
 | 
				
			||||||
 | 
					    const panel = this.panel;
 | 
				
			||||||
 | 
					    const content = this.#c("div", "c=continue, s=step");
 | 
				
			||||||
 | 
					    const table = this.#c("table");
 | 
				
			||||||
 | 
					    content.append(table);
 | 
				
			||||||
 | 
					    table.cellSpacing = 0;
 | 
				
			||||||
 | 
					    const headerRow = this.#c("tr");
 | 
				
			||||||
 | 
					    table.append(headerRow);
 | 
				
			||||||
 | 
					    headerRow.append(
 | 
				
			||||||
 | 
					      this.#c("th", "Break"),
 | 
				
			||||||
 | 
					      this.#c("th", "Idx"),
 | 
				
			||||||
 | 
					      this.#c("th", "fn"),
 | 
				
			||||||
 | 
					      this.#c("th", "args")
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    panel.append(content);
 | 
				
			||||||
 | 
					    this.table = table;
 | 
				
			||||||
 | 
					    this.updateOperatorList(operatorList);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  updateOperatorList(operatorList) {
 | 
				
			||||||
 | 
					    const self = this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function cboxOnClick() {
 | 
				
			||||||
 | 
					      const x = +this.dataset.idx;
 | 
				
			||||||
 | 
					      if (this.checked) {
 | 
				
			||||||
 | 
					        self.breakPoints.push(x);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        self.breakPoints.splice(self.breakPoints.indexOf(x), 1);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      StepperManager.saveBreakPoints(self.pageIndex, self.breakPoints);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    init(operatorList) {
 | 
					    const MAX_OPERATORS_COUNT = 15000;
 | 
				
			||||||
      const panel = this.panel;
 | 
					    if (this.operatorListIdx > MAX_OPERATORS_COUNT) {
 | 
				
			||||||
      const content = c("div", "c=continue, s=step");
 | 
					      return;
 | 
				
			||||||
      const table = c("table");
 | 
					 | 
				
			||||||
      content.append(table);
 | 
					 | 
				
			||||||
      table.cellSpacing = 0;
 | 
					 | 
				
			||||||
      const headerRow = c("tr");
 | 
					 | 
				
			||||||
      table.append(headerRow);
 | 
					 | 
				
			||||||
      headerRow.append(
 | 
					 | 
				
			||||||
        c("th", "Break"),
 | 
					 | 
				
			||||||
        c("th", "Idx"),
 | 
					 | 
				
			||||||
        c("th", "fn"),
 | 
					 | 
				
			||||||
        c("th", "args")
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
      panel.append(content);
 | 
					 | 
				
			||||||
      this.table = table;
 | 
					 | 
				
			||||||
      this.updateOperatorList(operatorList);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    updateOperatorList(operatorList) {
 | 
					    const chunk = document.createDocumentFragment();
 | 
				
			||||||
      const self = this;
 | 
					    const operatorsToDisplay = Math.min(
 | 
				
			||||||
 | 
					      MAX_OPERATORS_COUNT,
 | 
				
			||||||
 | 
					      operatorList.fnArray.length
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    for (let i = this.operatorListIdx; i < operatorsToDisplay; i++) {
 | 
				
			||||||
 | 
					      const line = this.#c("tr");
 | 
				
			||||||
 | 
					      line.className = "line";
 | 
				
			||||||
 | 
					      line.dataset.idx = i;
 | 
				
			||||||
 | 
					      chunk.append(line);
 | 
				
			||||||
 | 
					      const checked = this.breakPoints.includes(i);
 | 
				
			||||||
 | 
					      const args = operatorList.argsArray[i] || [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      function cboxOnClick() {
 | 
					      const breakCell = this.#c("td");
 | 
				
			||||||
        const x = +this.dataset.idx;
 | 
					      const cbox = this.#c("input");
 | 
				
			||||||
        if (this.checked) {
 | 
					      cbox.type = "checkbox";
 | 
				
			||||||
          self.breakPoints.push(x);
 | 
					      cbox.className = "points";
 | 
				
			||||||
        } else {
 | 
					      cbox.checked = checked;
 | 
				
			||||||
          self.breakPoints.splice(self.breakPoints.indexOf(x), 1);
 | 
					      cbox.dataset.idx = i;
 | 
				
			||||||
        }
 | 
					      cbox.onclick = cboxOnClick;
 | 
				
			||||||
        StepperManager.saveBreakPoints(self.pageIndex, self.breakPoints);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const MAX_OPERATORS_COUNT = 15000;
 | 
					      breakCell.append(cbox);
 | 
				
			||||||
      if (this.operatorListIdx > MAX_OPERATORS_COUNT) {
 | 
					      line.append(breakCell, this.#c("td", i.toString()));
 | 
				
			||||||
        return;
 | 
					      const fn = opMap[operatorList.fnArray[i]];
 | 
				
			||||||
      }
 | 
					      let decArgs = args;
 | 
				
			||||||
 | 
					      if (fn === "showText") {
 | 
				
			||||||
      const chunk = document.createDocumentFragment();
 | 
					        const glyphs = args[0];
 | 
				
			||||||
      const operatorsToDisplay = Math.min(
 | 
					        const charCodeRow = this.#c("tr");
 | 
				
			||||||
        MAX_OPERATORS_COUNT,
 | 
					        const fontCharRow = this.#c("tr");
 | 
				
			||||||
        operatorList.fnArray.length
 | 
					        const unicodeRow = this.#c("tr");
 | 
				
			||||||
      );
 | 
					        for (const glyph of glyphs) {
 | 
				
			||||||
      for (let i = this.operatorListIdx; i < operatorsToDisplay; i++) {
 | 
					          if (typeof glyph === "object" && glyph !== null) {
 | 
				
			||||||
        const line = c("tr");
 | 
					            charCodeRow.append(this.#c("td", glyph.originalCharCode));
 | 
				
			||||||
        line.className = "line";
 | 
					            fontCharRow.append(this.#c("td", glyph.fontChar));
 | 
				
			||||||
        line.dataset.idx = i;
 | 
					            unicodeRow.append(this.#c("td", glyph.unicode));
 | 
				
			||||||
        chunk.append(line);
 | 
					          } else {
 | 
				
			||||||
        const checked = this.breakPoints.includes(i);
 | 
					            // null or number
 | 
				
			||||||
        const args = operatorList.argsArray[i] || [];
 | 
					            const advanceEl = this.#c("td", glyph);
 | 
				
			||||||
 | 
					            advanceEl.classList.add("advance");
 | 
				
			||||||
        const breakCell = c("td");
 | 
					            charCodeRow.append(advanceEl);
 | 
				
			||||||
        const cbox = c("input");
 | 
					            fontCharRow.append(this.#c("td"));
 | 
				
			||||||
        cbox.type = "checkbox";
 | 
					            unicodeRow.append(this.#c("td"));
 | 
				
			||||||
        cbox.className = "points";
 | 
					 | 
				
			||||||
        cbox.checked = checked;
 | 
					 | 
				
			||||||
        cbox.dataset.idx = i;
 | 
					 | 
				
			||||||
        cbox.onclick = cboxOnClick;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        breakCell.append(cbox);
 | 
					 | 
				
			||||||
        line.append(breakCell, c("td", i.toString()));
 | 
					 | 
				
			||||||
        const fn = opMap[operatorList.fnArray[i]];
 | 
					 | 
				
			||||||
        let decArgs = args;
 | 
					 | 
				
			||||||
        if (fn === "showText") {
 | 
					 | 
				
			||||||
          const glyphs = args[0];
 | 
					 | 
				
			||||||
          const charCodeRow = c("tr");
 | 
					 | 
				
			||||||
          const fontCharRow = c("tr");
 | 
					 | 
				
			||||||
          const unicodeRow = c("tr");
 | 
					 | 
				
			||||||
          for (const glyph of glyphs) {
 | 
					 | 
				
			||||||
            if (typeof glyph === "object" && glyph !== null) {
 | 
					 | 
				
			||||||
              charCodeRow.append(c("td", glyph.originalCharCode));
 | 
					 | 
				
			||||||
              fontCharRow.append(c("td", glyph.fontChar));
 | 
					 | 
				
			||||||
              unicodeRow.append(c("td", glyph.unicode));
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
              // null or number
 | 
					 | 
				
			||||||
              const advanceEl = c("td", glyph);
 | 
					 | 
				
			||||||
              advanceEl.classList.add("advance");
 | 
					 | 
				
			||||||
              charCodeRow.append(advanceEl);
 | 
					 | 
				
			||||||
              fontCharRow.append(c("td"));
 | 
					 | 
				
			||||||
              unicodeRow.append(c("td"));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          decArgs = c("td");
 | 
					 | 
				
			||||||
          const table = c("table");
 | 
					 | 
				
			||||||
          table.classList.add("showText");
 | 
					 | 
				
			||||||
          decArgs.append(table);
 | 
					 | 
				
			||||||
          table.append(charCodeRow, fontCharRow, unicodeRow);
 | 
					 | 
				
			||||||
        } else if (fn === "restore" && this.indentLevel > 0) {
 | 
					 | 
				
			||||||
          this.indentLevel--;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        line.append(c("td", " ".repeat(this.indentLevel * 2) + fn));
 | 
					 | 
				
			||||||
        if (fn === "save") {
 | 
					 | 
				
			||||||
          this.indentLevel++;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (decArgs instanceof HTMLElement) {
 | 
					 | 
				
			||||||
          line.append(decArgs);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          line.append(c("td", JSON.stringify(simplifyArgs(decArgs))));
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        decArgs = this.#c("td");
 | 
				
			||||||
 | 
					        const table = this.#c("table");
 | 
				
			||||||
 | 
					        table.classList.add("showText");
 | 
				
			||||||
 | 
					        decArgs.append(table);
 | 
				
			||||||
 | 
					        table.append(charCodeRow, fontCharRow, unicodeRow);
 | 
				
			||||||
 | 
					      } else if (fn === "restore" && this.indentLevel > 0) {
 | 
				
			||||||
 | 
					        this.indentLevel--;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (operatorsToDisplay < operatorList.fnArray.length) {
 | 
					      line.append(this.#c("td", " ".repeat(this.indentLevel * 2) + fn));
 | 
				
			||||||
        const lastCell = c("td", "...");
 | 
					      if (fn === "save") {
 | 
				
			||||||
        lastCell.colspan = 4;
 | 
					        this.indentLevel++;
 | 
				
			||||||
        chunk.append(lastCell);
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      this.operatorListIdx = operatorList.fnArray.length;
 | 
					 | 
				
			||||||
      this.table.append(chunk);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    getNextBreakPoint() {
 | 
					      if (decArgs instanceof HTMLElement) {
 | 
				
			||||||
      this.breakPoints.sort(function (a, b) {
 | 
					        line.append(decArgs);
 | 
				
			||||||
        return a - b;
 | 
					      } else {
 | 
				
			||||||
      });
 | 
					        line.append(this.#c("td", JSON.stringify(this.#simplifyArgs(decArgs))));
 | 
				
			||||||
      for (const breakPoint of this.breakPoints) {
 | 
					 | 
				
			||||||
        if (breakPoint > this.currentIdx) {
 | 
					 | 
				
			||||||
          return breakPoint;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return null;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (operatorsToDisplay < operatorList.fnArray.length) {
 | 
				
			||||||
    breakIt(idx, callback) {
 | 
					      const lastCell = this.#c("td", "...");
 | 
				
			||||||
      StepperManager.selectStepper(this.pageIndex, true);
 | 
					      lastCell.colspan = 4;
 | 
				
			||||||
      this.currentIdx = idx;
 | 
					      chunk.append(lastCell);
 | 
				
			||||||
 | 
					 | 
				
			||||||
      const listener = evt => {
 | 
					 | 
				
			||||||
        switch (evt.keyCode) {
 | 
					 | 
				
			||||||
          case 83: // step
 | 
					 | 
				
			||||||
            document.removeEventListener("keydown", listener);
 | 
					 | 
				
			||||||
            this.nextBreakPoint = this.currentIdx + 1;
 | 
					 | 
				
			||||||
            this.goTo(-1);
 | 
					 | 
				
			||||||
            callback();
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          case 67: // continue
 | 
					 | 
				
			||||||
            document.removeEventListener("keydown", listener);
 | 
					 | 
				
			||||||
            this.nextBreakPoint = this.getNextBreakPoint();
 | 
					 | 
				
			||||||
            this.goTo(-1);
 | 
					 | 
				
			||||||
            callback();
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      document.addEventListener("keydown", listener);
 | 
					 | 
				
			||||||
      this.goTo(idx);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    this.operatorListIdx = operatorList.fnArray.length;
 | 
				
			||||||
 | 
					    this.table.append(chunk);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    goTo(idx) {
 | 
					  getNextBreakPoint() {
 | 
				
			||||||
      const allRows = this.panel.getElementsByClassName("line");
 | 
					    this.breakPoints.sort(function (a, b) {
 | 
				
			||||||
      for (const row of allRows) {
 | 
					      return a - b;
 | 
				
			||||||
        if ((row.dataset.idx | 0) === idx) {
 | 
					    });
 | 
				
			||||||
          row.style.backgroundColor = "rgb(251,250,207)";
 | 
					    for (const breakPoint of this.breakPoints) {
 | 
				
			||||||
          row.scrollIntoView();
 | 
					      if (breakPoint > this.currentIdx) {
 | 
				
			||||||
        } else {
 | 
					        return breakPoint;
 | 
				
			||||||
          row.style.backgroundColor = null;
 | 
					      }
 | 
				
			||||||
        }
 | 
					    }
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  breakIt(idx, callback) {
 | 
				
			||||||
 | 
					    StepperManager.selectStepper(this.pageIndex, true);
 | 
				
			||||||
 | 
					    this.currentIdx = idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const listener = evt => {
 | 
				
			||||||
 | 
					      switch (evt.keyCode) {
 | 
				
			||||||
 | 
					        case 83: // step
 | 
				
			||||||
 | 
					          document.removeEventListener("keydown", listener);
 | 
				
			||||||
 | 
					          this.nextBreakPoint = this.currentIdx + 1;
 | 
				
			||||||
 | 
					          this.goTo(-1);
 | 
				
			||||||
 | 
					          callback();
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case 67: // continue
 | 
				
			||||||
 | 
					          document.removeEventListener("keydown", listener);
 | 
				
			||||||
 | 
					          this.nextBreakPoint = this.getNextBreakPoint();
 | 
				
			||||||
 | 
					          this.goTo(-1);
 | 
				
			||||||
 | 
					          callback();
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    document.addEventListener("keydown", listener);
 | 
				
			||||||
 | 
					    this.goTo(idx);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  goTo(idx) {
 | 
				
			||||||
 | 
					    const allRows = this.panel.getElementsByClassName("line");
 | 
				
			||||||
 | 
					    for (const row of allRows) {
 | 
				
			||||||
 | 
					      if ((row.dataset.idx | 0) === idx) {
 | 
				
			||||||
 | 
					        row.style.backgroundColor = "rgb(251,250,207)";
 | 
				
			||||||
 | 
					        row.scrollIntoView();
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        row.style.backgroundColor = null;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return Stepper;
 | 
					}
 | 
				
			||||||
})();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Stats = (function Stats() {
 | 
					const Stats = (function Stats() {
 | 
				
			||||||
  let stats = [];
 | 
					  let stats = [];
 | 
				
			||||||
@ -495,115 +491,118 @@ const Stats = (function Stats() {
 | 
				
			|||||||
})();
 | 
					})();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Manages all the debugging tools.
 | 
					// Manages all the debugging tools.
 | 
				
			||||||
const PDFBug = (function PDFBugClosure() {
 | 
					class PDFBug {
 | 
				
			||||||
  const panelWidth = 300;
 | 
					  static #buttons = [];
 | 
				
			||||||
  const buttons = [];
 | 
					 | 
				
			||||||
  let activePanel = null;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return {
 | 
					  static #activePanel = null;
 | 
				
			||||||
    tools: [FontInspector, StepperManager, Stats],
 | 
					 | 
				
			||||||
    enable(ids) {
 | 
					 | 
				
			||||||
      const all = ids.length === 1 && ids[0] === "all";
 | 
					 | 
				
			||||||
      const tools = this.tools;
 | 
					 | 
				
			||||||
      for (const tool of tools) {
 | 
					 | 
				
			||||||
        if (all || ids.includes(tool.id)) {
 | 
					 | 
				
			||||||
          tool.enabled = true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (!all) {
 | 
					 | 
				
			||||||
        // Sort the tools by the order they are enabled.
 | 
					 | 
				
			||||||
        tools.sort(function (a, b) {
 | 
					 | 
				
			||||||
          let indexA = ids.indexOf(a.id);
 | 
					 | 
				
			||||||
          indexA = indexA < 0 ? tools.length : indexA;
 | 
					 | 
				
			||||||
          let indexB = ids.indexOf(b.id);
 | 
					 | 
				
			||||||
          indexB = indexB < 0 ? tools.length : indexB;
 | 
					 | 
				
			||||||
          return indexA - indexB;
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    init(container, ids) {
 | 
					 | 
				
			||||||
      this.loadCSS();
 | 
					 | 
				
			||||||
      this.enable(ids);
 | 
					 | 
				
			||||||
      /*
 | 
					 | 
				
			||||||
       * Basic Layout:
 | 
					 | 
				
			||||||
       * PDFBug
 | 
					 | 
				
			||||||
       *  Controls
 | 
					 | 
				
			||||||
       *  Panels
 | 
					 | 
				
			||||||
       *    Panel
 | 
					 | 
				
			||||||
       *    Panel
 | 
					 | 
				
			||||||
       *    ...
 | 
					 | 
				
			||||||
       */
 | 
					 | 
				
			||||||
      const ui = document.createElement("div");
 | 
					 | 
				
			||||||
      ui.id = "PDFBug";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const controls = document.createElement("div");
 | 
					  static tools = [FontInspector, StepperManager, Stats];
 | 
				
			||||||
      controls.setAttribute("class", "controls");
 | 
					 | 
				
			||||||
      ui.append(controls);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const panels = document.createElement("div");
 | 
					  static enable(ids) {
 | 
				
			||||||
      panels.setAttribute("class", "panels");
 | 
					    const all = ids.length === 1 && ids[0] === "all";
 | 
				
			||||||
      ui.append(panels);
 | 
					    const tools = this.tools;
 | 
				
			||||||
 | 
					    for (const tool of tools) {
 | 
				
			||||||
 | 
					      if (all || ids.includes(tool.id)) {
 | 
				
			||||||
 | 
					        tool.enabled = true;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!all) {
 | 
				
			||||||
 | 
					      // Sort the tools by the order they are enabled.
 | 
				
			||||||
 | 
					      tools.sort(function (a, b) {
 | 
				
			||||||
 | 
					        let indexA = ids.indexOf(a.id);
 | 
				
			||||||
 | 
					        indexA = indexA < 0 ? tools.length : indexA;
 | 
				
			||||||
 | 
					        let indexB = ids.indexOf(b.id);
 | 
				
			||||||
 | 
					        indexB = indexB < 0 ? tools.length : indexB;
 | 
				
			||||||
 | 
					        return indexA - indexB;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      container.append(ui);
 | 
					  static init(container, ids) {
 | 
				
			||||||
      container.style.right = panelWidth + "px";
 | 
					    this.loadCSS();
 | 
				
			||||||
 | 
					    this.enable(ids);
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Basic Layout:
 | 
				
			||||||
 | 
					     * PDFBug
 | 
				
			||||||
 | 
					     *  Controls
 | 
				
			||||||
 | 
					     *  Panels
 | 
				
			||||||
 | 
					     *    Panel
 | 
				
			||||||
 | 
					     *    Panel
 | 
				
			||||||
 | 
					     *    ...
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    const ui = document.createElement("div");
 | 
				
			||||||
 | 
					    ui.id = "PDFBug";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Initialize all the debugging tools.
 | 
					    const controls = document.createElement("div");
 | 
				
			||||||
      for (const tool of this.tools) {
 | 
					    controls.setAttribute("class", "controls");
 | 
				
			||||||
        const panel = document.createElement("div");
 | 
					    ui.append(controls);
 | 
				
			||||||
        const panelButton = document.createElement("button");
 | 
					 | 
				
			||||||
        panelButton.textContent = tool.name;
 | 
					 | 
				
			||||||
        panelButton.addEventListener("click", event => {
 | 
					 | 
				
			||||||
          event.preventDefault();
 | 
					 | 
				
			||||||
          this.selectPanel(tool);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        controls.append(panelButton);
 | 
					 | 
				
			||||||
        panels.append(panel);
 | 
					 | 
				
			||||||
        tool.panel = panel;
 | 
					 | 
				
			||||||
        tool.manager = this;
 | 
					 | 
				
			||||||
        if (tool.enabled) {
 | 
					 | 
				
			||||||
          tool.init();
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          panel.textContent =
 | 
					 | 
				
			||||||
            `${tool.name} is disabled. To enable add "${tool.id}" to ` +
 | 
					 | 
				
			||||||
            "the pdfBug parameter and refresh (separate multiple by commas).";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        buttons.push(panelButton);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      this.selectPanel(0);
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    loadCSS() {
 | 
					 | 
				
			||||||
      const { url } = import.meta;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const link = document.createElement("link");
 | 
					    const panels = document.createElement("div");
 | 
				
			||||||
      link.rel = "stylesheet";
 | 
					    panels.setAttribute("class", "panels");
 | 
				
			||||||
      link.href = url.replace(/.js$/, ".css");
 | 
					    ui.append(panels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      document.head.append(link);
 | 
					    container.append(ui);
 | 
				
			||||||
    },
 | 
					    container.style.right = "var(--panel-width)";
 | 
				
			||||||
    cleanup() {
 | 
					
 | 
				
			||||||
      for (const tool of this.tools) {
 | 
					    // Initialize all the debugging tools.
 | 
				
			||||||
        if (tool.enabled) {
 | 
					    for (const tool of this.tools) {
 | 
				
			||||||
          tool.cleanup();
 | 
					      const panel = document.createElement("div");
 | 
				
			||||||
        }
 | 
					      const panelButton = document.createElement("button");
 | 
				
			||||||
 | 
					      panelButton.textContent = tool.name;
 | 
				
			||||||
 | 
					      panelButton.addEventListener("click", event => {
 | 
				
			||||||
 | 
					        event.preventDefault();
 | 
				
			||||||
 | 
					        this.selectPanel(tool);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      controls.append(panelButton);
 | 
				
			||||||
 | 
					      panels.append(panel);
 | 
				
			||||||
 | 
					      tool.panel = panel;
 | 
				
			||||||
 | 
					      tool.manager = this;
 | 
				
			||||||
 | 
					      if (tool.enabled) {
 | 
				
			||||||
 | 
					        tool.init();
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        panel.textContent =
 | 
				
			||||||
 | 
					          `${tool.name} is disabled. To enable add "${tool.id}" to ` +
 | 
				
			||||||
 | 
					          "the pdfBug parameter and refresh (separate multiple by commas).";
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					      this.#buttons.push(panelButton);
 | 
				
			||||||
    selectPanel(index) {
 | 
					    }
 | 
				
			||||||
      if (typeof index !== "number") {
 | 
					    this.selectPanel(0);
 | 
				
			||||||
        index = this.tools.indexOf(index);
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static loadCSS() {
 | 
				
			||||||
 | 
					    const { url } = import.meta;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const link = document.createElement("link");
 | 
				
			||||||
 | 
					    link.rel = "stylesheet";
 | 
				
			||||||
 | 
					    link.href = url.replace(/.js$/, ".css");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    document.head.append(link);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static cleanup() {
 | 
				
			||||||
 | 
					    for (const tool of this.tools) {
 | 
				
			||||||
 | 
					      if (tool.enabled) {
 | 
				
			||||||
 | 
					        tool.cleanup();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (index === activePanel) {
 | 
					    }
 | 
				
			||||||
        return;
 | 
					  }
 | 
				
			||||||
      }
 | 
					
 | 
				
			||||||
      activePanel = index;
 | 
					  static selectPanel(index) {
 | 
				
			||||||
      for (const [j, tool] of this.tools.entries()) {
 | 
					    if (typeof index !== "number") {
 | 
				
			||||||
        const isActive = j === index;
 | 
					      index = this.tools.indexOf(index);
 | 
				
			||||||
        buttons[j].classList.toggle("active", isActive);
 | 
					    }
 | 
				
			||||||
        tool.active = isActive;
 | 
					    if (index === this.#activePanel) {
 | 
				
			||||||
        tool.panel.hidden = !isActive;
 | 
					      return;
 | 
				
			||||||
      }
 | 
					    }
 | 
				
			||||||
    },
 | 
					    this.#activePanel = index;
 | 
				
			||||||
  };
 | 
					    for (const [j, tool] of this.tools.entries()) {
 | 
				
			||||||
})();
 | 
					      const isActive = j === index;
 | 
				
			||||||
 | 
					      this.#buttons[j].classList.toggle("active", isActive);
 | 
				
			||||||
 | 
					      tool.active = isActive;
 | 
				
			||||||
 | 
					      tool.panel.hidden = !isActive;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
globalThis.FontInspector = FontInspector;
 | 
					globalThis.FontInspector = FontInspector;
 | 
				
			||||||
globalThis.StepperManager = StepperManager;
 | 
					globalThis.StepperManager = StepperManager;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user