Skip to content

Commit 45578aa

Browse files
committed
Create a sidebar object
For now its use is limited to the comment sidebar but it'll be used for the new one containing the thumbnails. And make the sidebar more accessible with the keyboard or a screen reader.
1 parent ec71e4e commit 45578aa

File tree

5 files changed

+252
-85
lines changed

5 files changed

+252
-85
lines changed

test/integration/comment_spec.mjs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import {
2121
getEditorSelector,
2222
getRect,
2323
highlightSpan,
24+
kbModifierDown,
25+
kbModifierUp,
2426
loadAndWait,
2527
scrollIntoView,
2628
selectEditor,
@@ -545,6 +547,59 @@ describe("Comment", () => {
545547
);
546548
});
547549

550+
it("must check that the comment sidebar is resizable with the keyboard", async () => {
551+
await Promise.all(
552+
pages.map(async ([browserName, page]) => {
553+
await switchToComment(page);
554+
555+
const sidebarSelector = "#editorCommentParamsToolbar";
556+
const handle = await createPromise(page, resolve => {
557+
document
558+
.getElementById("editorCommentsSidebarResizer")
559+
.addEventListener("focus", () => resolve(), { once: true });
560+
});
561+
await page.focus(`${sidebarSelector} #editorCommentsSidebarResizer`);
562+
await awaitPromise(handle);
563+
564+
// Use Ctrl+ArrowLeft/Right to resize the sidebar.
565+
for (const extraWidth of [10, -10]) {
566+
const rect = await getRect(page, sidebarSelector);
567+
const arrowKey = extraWidth > 0 ? "ArrowLeft" : "ArrowRight";
568+
for (let i = 0; i < Math.abs(extraWidth); i++) {
569+
await kbModifierDown(page);
570+
await page.keyboard.press(arrowKey);
571+
await kbModifierUp(page);
572+
}
573+
574+
const rectAfter = await getRect(page, sidebarSelector);
575+
expect(Math.abs(rectAfter.width - (rect.width + 10 * extraWidth)))
576+
.withContext(`In ${browserName}`)
577+
.toBeLessThanOrEqual(1);
578+
expect(Math.abs(rectAfter.x - (rect.x - 10 * extraWidth)))
579+
.withContext(`In ${browserName}`)
580+
.toBeLessThanOrEqual(1);
581+
}
582+
583+
// Use ArrowLeft/Right to resize the sidebar.
584+
for (const extraWidth of [10, -10]) {
585+
const rect = await getRect(page, sidebarSelector);
586+
const arrowKey = extraWidth > 0 ? "ArrowLeft" : "ArrowRight";
587+
for (let i = 0; i < Math.abs(extraWidth); i++) {
588+
await page.keyboard.press(arrowKey);
589+
}
590+
591+
const rectAfter = await getRect(page, sidebarSelector);
592+
expect(Math.abs(rectAfter.width - (rect.width + extraWidth)))
593+
.withContext(`In ${browserName}`)
594+
.toBeLessThanOrEqual(1);
595+
expect(Math.abs(rectAfter.x - (rect.x - extraWidth)))
596+
.withContext(`In ${browserName}`)
597+
.toBeLessThanOrEqual(1);
598+
}
599+
})
600+
);
601+
});
602+
548603
it("must check that comments are in chronological order", async () => {
549604
await Promise.all(
550605
pages.map(async ([browserName, page]) => {

web/comment_manager.js

Lines changed: 10 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
Util,
2828
} from "pdfjs-lib";
2929
import { binarySearchFirstItem } from "./ui_utils.js";
30+
import { Sidebar } from "./sidebar.js";
3031

3132
class CommentManager {
3233
#dialog;
@@ -141,7 +142,7 @@ class CommentManager {
141142
}
142143
}
143144

144-
class CommentSidebar {
145+
class CommentSidebar extends Sidebar {
145146
#annotations = null;
146147

147148
#eventBus;
@@ -150,8 +151,6 @@ class CommentSidebar {
150151

151152
#boundCommentKeydown = this.#commentKeydown.bind(this);
152153

153-
#sidebar;
154-
155154
#closeButton;
156155

157156
#commentsList;
@@ -174,16 +173,6 @@ class CommentSidebar {
174173

175174
#uiManager = null;
176175

177-
#minWidth = 0;
178-
179-
#maxWidth = 0;
180-
181-
#initialWidth = 0;
182-
183-
#width = 0;
184-
185-
#ltr;
186-
187176
constructor(
188177
{
189178
learnMoreUrl,
@@ -201,7 +190,11 @@ class CommentSidebar {
201190
dateFormat,
202191
ltr
203192
) {
204-
this.#sidebar = sidebar;
193+
super(
194+
{ sidebar, resizer: sidebarResizer, toggleButton: commentToolbarButton },
195+
ltr,
196+
/* isResizerOnTheLeft = */ true
197+
);
205198
this.#sidebarTitle = sidebarTitle;
206199
this.#commentsList = commentsList;
207200
this.#commentCount = commentCount;
@@ -210,17 +203,8 @@ class CommentSidebar {
210203
this.#closeButton = closeButton;
211204
this.#popup = popup;
212205
this.#dateFormat = dateFormat;
213-
this.#ltr = ltr;
214206
this.#eventBus = eventBus;
215207

216-
const style = window.getComputedStyle(sidebar);
217-
this.#minWidth = parseFloat(style.getPropertyValue("--sidebar-min-width"));
218-
this.#maxWidth = parseFloat(style.getPropertyValue("--sidebar-max-width"));
219-
this.#initialWidth = this.#width = parseFloat(
220-
style.getPropertyValue("--sidebar-width")
221-
);
222-
223-
this.#makeSidebarResizable(sidebarResizer);
224208
closeButton.addEventListener("click", () => {
225209
eventBus.dispatch("switchannotationeditormode", {
226210
source: this,
@@ -238,64 +222,6 @@ class CommentSidebar {
238222
};
239223
commentToolbarButton.addEventListener("keydown", keyDownCallback);
240224
sidebar.addEventListener("keydown", keyDownCallback);
241-
this.#sidebar.hidden = true;
242-
}
243-
244-
#makeSidebarResizable(resizer) {
245-
let pointerMoveAC;
246-
const cancelResize = () => {
247-
this.#width = MathClamp(this.#width, this.#minWidth, this.#maxWidth);
248-
this.#sidebar.classList.remove("resizing");
249-
pointerMoveAC?.abort();
250-
pointerMoveAC = null;
251-
};
252-
resizer.addEventListener("pointerdown", e => {
253-
if (pointerMoveAC) {
254-
cancelResize();
255-
return;
256-
}
257-
const { clientX } = e;
258-
stopEvent(e);
259-
let prevX = clientX;
260-
pointerMoveAC = new AbortController();
261-
const { signal } = pointerMoveAC;
262-
const sign = this.#ltr ? -1 : 1;
263-
const sidebar = this.#sidebar;
264-
const sidebarStyle = sidebar.style;
265-
sidebar.classList.add("resizing");
266-
const parentStyle = sidebar.parentElement.style;
267-
parentStyle.minWidth = 0;
268-
window.addEventListener("contextmenu", noContextMenu, { signal });
269-
window.addEventListener(
270-
"pointermove",
271-
ev => {
272-
if (!pointerMoveAC) {
273-
return;
274-
}
275-
stopEvent(ev);
276-
const { clientX: x } = ev;
277-
const newWidth = (this.#width += sign * (x - prevX));
278-
prevX = x;
279-
if (newWidth > this.#maxWidth || newWidth < this.#minWidth) {
280-
return;
281-
}
282-
sidebarStyle.width = `${newWidth.toFixed(3)}px`;
283-
parentStyle.insetInlineStart = `${(this.#initialWidth - newWidth).toFixed(3)}px`;
284-
},
285-
{ signal, capture: true }
286-
);
287-
window.addEventListener("blur", cancelResize, { signal });
288-
window.addEventListener(
289-
"pointerup",
290-
ev => {
291-
if (pointerMoveAC) {
292-
cancelResize();
293-
stopEvent(ev);
294-
}
295-
},
296-
{ signal }
297-
);
298-
});
299225
}
300226

301227
setUIManager(uiManager) {
@@ -318,7 +244,7 @@ class CommentSidebar {
318244
} else {
319245
this.#setCommentsCount();
320246
}
321-
this.#sidebar.hidden = false;
247+
this._sidebar.hidden = false;
322248
this.#eventBus.dispatch("reporttelemetry", {
323249
source: this,
324250
details: {
@@ -329,7 +255,7 @@ class CommentSidebar {
329255
}
330256

331257
hide() {
332-
this.#sidebar.hidden = true;
258+
this._sidebar.hidden = true;
333259
this.#commentsList.replaceChildren();
334260
this.#elementsToAnnotations = null;
335261
this.#idsToElements = null;
@@ -356,7 +282,7 @@ class CommentSidebar {
356282
if (!element) {
357283
return;
358284
}
359-
this.#sidebar.scrollTop = element.offsetTop - this.#sidebar.offsetTop;
285+
this._sidebar.scrollTop = element.offsetTop - this._sidebar.offsetTop;
360286
for (const el of this.#commentsList.children) {
361287
el.classList.toggle("selected", el === element);
362288
}

web/sidebar.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
--sidebar-box-shadow:
2323
0 0.25px 0.75px light-dark(rgb(0 0 0 / 0.05), rgb(0 0 0 / 0.2)),
2424
0 2px 6px 0 light-dark(rgb(0 0 0 / 0.1), rgb(0 0 0 / 0.4));
25+
--sidebar-backdrop-filter: none;
2526
--sidebar-border-radius: 8px;
2627
--sidebar-padding: 5px;
2728
--sidebar-min-width: 180px;
@@ -46,6 +47,7 @@
4647
width: var(--sidebar-width);
4748
min-width: var(--sidebar-min-width);
4849
max-width: var(--sidebar-max-width);
50+
backdrop-filter: var(--sidebar-backdrop-filter);
4951

5052
.sidebarResizer {
5153
width: var(--resizer-width);
@@ -64,6 +66,10 @@
6466
&:hover {
6567
background-color: var(--resizer-hover-bg-color);
6668
}
69+
&:focus-visible {
70+
background-color: var(--resizer-hover-bg-color);
71+
outline: none;
72+
}
6773
}
6874

6975
&.resizing {

0 commit comments

Comments
 (0)