Skip to content

Commit 0a2c030

Browse files
Merge pull request #20888 from calixteman/debugger_skip_ops
Add the possibility to skip some ops in the debug view
2 parents 481a0cb + e85c30e commit 0a2c030

5 files changed

Lines changed: 76 additions & 22 deletions

File tree

src/display/canvas.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -786,9 +786,15 @@ class CanvasGraphics {
786786
let fnId, fnArgs;
787787

788788
while (true) {
789-
if (stepper !== undefined && i === stepper.nextBreakPoint) {
790-
stepper.breakIt(i, continueCallback);
791-
return i;
789+
if (stepper !== undefined) {
790+
if (i === stepper.nextBreakPoint) {
791+
stepper.breakIt(i, continueCallback);
792+
return i;
793+
}
794+
if (stepper.shouldSkip(i)) {
795+
i++;
796+
continue;
797+
}
792798
}
793799

794800
if (!operationsFilter || operationsFilter(i)) {

web/debugger.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,10 @@ class Stepper {
659659
this.goTo(idx);
660660
}
661661

662+
shouldSkip(idx) {
663+
return false;
664+
}
665+
662666
goTo(idx) {
663667
const allRows = this.panel.getElementsByClassName("line");
664668
for (const row of allRows) {

web/internal/draw_ops_view.css

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,17 +159,25 @@
159159
&::before {
160160
content: "●";
161161
color: var(--changed-color);
162-
font-size: 0.75em;
162+
font-size: 0.9em;
163163
opacity: 0;
164164
}
165165

166166
&:hover::before {
167167
opacity: 0.4;
168168
}
169169

170-
&.active::before {
170+
&[data-bp="pause"]::before {
171171
opacity: 1;
172172
}
173+
174+
&[data-bp="skip"]::before {
175+
content: "✕";
176+
opacity: 1;
177+
}
178+
}
179+
.op-line.op-skipped > :not(.bp-gutter) {
180+
opacity: 0.4;
173181
}
174182
.op-line.paused {
175183
background: var(--paused-bg);
@@ -194,9 +202,16 @@
194202
.bp-gutter:hover::before {
195203
color: ButtonBorder;
196204
}
197-
.bp-gutter.active::before {
205+
.bp-gutter[data-bp="pause"]::before {
198206
color: ButtonText;
199207
}
208+
.bp-gutter[data-bp="skip"]::before {
209+
color: ButtonText;
210+
}
211+
.op-line.op-skipped > :not(.bp-gutter) {
212+
opacity: 1;
213+
color: GrayText;
214+
}
200215

201216
/* Color swatch preserves the actual PDF color value. */
202217
.color-swatch {

web/internal/draw_ops_view.js

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ for (const [name, id] of Object.entries(OPS)) {
2323
OPS_TO_NAME[id] = name;
2424
}
2525

26+
const BreakpointType = {
27+
PAUSE: 0,
28+
SKIP: 1,
29+
};
30+
2631
// Single hidden color input reused for all swatch pickers.
2732
const colorPickerInput = document.createElement("input");
2833
colorPickerInput.type = "color";
@@ -408,7 +413,8 @@ class DrawOpsView {
408413

409414
#selectedLine = null;
410415

411-
#breakpoints = new Set();
416+
// Map<opIndex, BreakpointType>
417+
#breakpoints = new Map();
412418

413419
#originalColors = new Map();
414420

@@ -553,27 +559,40 @@ class DrawOpsView {
553559
line.ariaSelected = "false";
554560
line.tabIndex = i === 0 ? 0 : -1;
555561

556-
// Breakpoint gutter — click to toggle a red-bullet breakpoint.
562+
// Breakpoint gutter — click cycles: none → pause (●) → skip (✕) → none.
557563
const gutter = document.createElement("span");
558564
gutter.className = "bp-gutter";
559565
gutter.role = "checkbox";
560566
gutter.tabIndex = 0;
561567
gutter.ariaLabel = "Breakpoint";
562-
const isInitiallyActive = this.#breakpoints.has(i);
563-
gutter.ariaChecked = String(isInitiallyActive);
564-
if (isInitiallyActive) {
565-
gutter.classList.add("active");
568+
const initBpType = this.#breakpoints.get(i);
569+
if (initBpType === BreakpointType.PAUSE) {
570+
gutter.dataset.bp = "pause";
571+
gutter.ariaChecked = "true";
572+
} else if (initBpType === BreakpointType.SKIP) {
573+
gutter.dataset.bp = "skip";
574+
gutter.ariaChecked = "mixed";
575+
line.classList.add("op-skipped");
576+
} else {
577+
gutter.ariaChecked = "false";
566578
}
567579
gutter.addEventListener("click", e => {
568580
e.stopPropagation();
569-
if (this.#breakpoints.has(i)) {
581+
const current = this.#breakpoints.get(i);
582+
if (current === undefined) {
583+
this.#breakpoints.set(i, BreakpointType.PAUSE);
584+
gutter.dataset.bp = "pause";
585+
gutter.ariaChecked = "true";
586+
} else if (current === BreakpointType.PAUSE) {
587+
this.#breakpoints.set(i, BreakpointType.SKIP);
588+
gutter.dataset.bp = "skip";
589+
gutter.ariaChecked = "mixed";
590+
line.classList.add("op-skipped");
591+
} else {
570592
this.#breakpoints.delete(i);
571-
gutter.classList.remove("active");
593+
delete gutter.dataset.bp;
572594
gutter.ariaChecked = "false";
573-
} else {
574-
this.#breakpoints.add(i);
575-
gutter.classList.add("active");
576-
gutter.ariaChecked = "true";
595+
line.classList.remove("op-skipped");
577596
}
578597
});
579598
gutter.addEventListener("keydown", e => {
@@ -656,4 +675,4 @@ class DrawOpsView {
656675
}
657676
}
658677

659-
export { DrawOpsView };
678+
export { BreakpointType, DrawOpsView };

web/internal/page_view.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
* limitations under the License.
1414
*/
1515

16+
import { BreakpointType, DrawOpsView } from "./draw_ops_view.js";
1617
import { CanvasContextDetailsView } from "./canvas_context_details_view.js";
1718
import { DOMCanvasFactory } from "pdfjs/display/canvas_factory.js";
18-
import { DrawOpsView } from "./draw_ops_view.js";
1919
import { SplitView } from "./split_view.js";
2020

2121
// Stepper for pausing/stepping through op list rendering.
@@ -61,10 +61,20 @@ class ViewerStepper {
6161
cb();
6262
}
6363

64+
shouldSkip(i) {
65+
return (
66+
globalThis.StepperManager._breakpoints.get(i) === BreakpointType.SKIP
67+
);
68+
}
69+
6470
#findNextAfter(idx) {
6571
let next = null;
66-
for (const bp of globalThis.StepperManager._breakpoints) {
67-
if (bp > idx && (next === null || bp < next)) {
72+
for (const [bp, type] of globalThis.StepperManager._breakpoints) {
73+
if (
74+
type === BreakpointType.PAUSE &&
75+
bp > idx &&
76+
(next === null || bp < next)
77+
) {
6878
next = bp;
6979
}
7080
}

0 commit comments

Comments
 (0)