Skip to content

Commit e85c30e

Browse files
committed
Add the possibility to skip some ops in the debug view
The user has to click in the space before an op to add a breakpoint and click again in order to skip it.
1 parent 1192e5e commit e85c30e

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
@@ -787,9 +787,15 @@ class CanvasGraphics {
787787
let fnId, fnArgs;
788788

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

795801
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)