Skip to content

Commit d63aabd

Browse files
authored
Merge pull request #19969 from calixteman/editor_inconsistencies
[Editor] Change mode when double clicking on an editor
2 parents 712d502 + 47e69e9 commit d63aabd

File tree

7 files changed

+152
-48
lines changed

7 files changed

+152
-48
lines changed

src/display/editor/annotation_editor_layer.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,10 @@ class AnnotationEditorLayer {
148148

149149
/**
150150
* Update the toolbar if it's required to reflect the tool currently used.
151-
* @param {number} mode
151+
* @param {Object} options
152152
*/
153-
updateToolbar(mode) {
154-
this.#uiManager.updateToolbar(mode);
153+
updateToolbar(options) {
154+
this.#uiManager.updateToolbar(options);
155155
}
156156

157157
/**
@@ -618,12 +618,12 @@ class AnnotationEditorLayer {
618618

619619
/**
620620
* Paste some content into a new editor.
621-
* @param {number} mode
621+
* @param {Object} options
622622
* @param {Object} params
623623
*/
624-
async pasteEditor(mode, params) {
625-
this.#uiManager.updateToolbar(mode);
626-
await this.#uiManager.updateMode(mode);
624+
async pasteEditor(options, params) {
625+
this.updateToolbar(options);
626+
await this.#uiManager.updateMode(options.mode);
627627

628628
const { offsetX, offsetY } = this.#getCenterPoint();
629629
const id = this.getNextId();

src/display/editor/editor.js

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ class AnnotationEditor {
9090

9191
#touchManager = null;
9292

93+
isSelected = false;
94+
9395
_isCopy = false;
9496

9597
_editToolbar = null;
@@ -1170,7 +1172,7 @@ class AnnotationEditor {
11701172
const [tx, ty] = this.getInitialTranslation();
11711173
this.translate(tx, ty);
11721174

1173-
bindEvents(this, div, ["keydown", "pointerdown"]);
1175+
bindEvents(this, div, ["keydown", "pointerdown", "dblclick"]);
11741176

11751177
if (this.isResizable && this._uiManager._supportsPinchToZoom) {
11761178
this.#touchManager ||= new TouchManager({
@@ -1279,10 +1281,6 @@ class AnnotationEditor {
12791281
this.#selectOnPointerEvent(event);
12801282
}
12811283

1282-
get isSelected() {
1283-
return this._uiManager.isSelected(this);
1284-
}
1285-
12861284
#selectOnPointerEvent(event) {
12871285
const { isMac } = FeatureTest.platform;
12881286
if (
@@ -1499,16 +1497,30 @@ class AnnotationEditor {
14991497

15001498
/**
15011499
* Enable edit mode.
1500+
* @returns {boolean} - true if the edit mode has been enabled.
15021501
*/
15031502
enableEditMode() {
1503+
if (this.isInEditMode()) {
1504+
return false;
1505+
}
1506+
this.parent.setEditingState(false);
15041507
this.#isInEditMode = true;
1508+
1509+
return true;
15051510
}
15061511

15071512
/**
15081513
* Disable edit mode.
1514+
* @returns {boolean} - true if the edit mode has been disabled.
15091515
*/
15101516
disableEditMode() {
1517+
if (!this.isInEditMode()) {
1518+
return false;
1519+
}
1520+
this.parent.setEditingState(true);
15111521
this.#isInEditMode = false;
1522+
1523+
return true;
15121524
}
15131525

15141526
/**
@@ -1832,6 +1844,10 @@ class AnnotationEditor {
18321844
* Select this editor.
18331845
*/
18341846
select() {
1847+
if (this.isSelected && this._editToolbar) {
1848+
return;
1849+
}
1850+
this.isSelected = true;
18351851
this.makeResizable();
18361852
this.div?.classList.add("selectedEditor");
18371853
if (!this._editToolbar) {
@@ -1853,6 +1869,10 @@ class AnnotationEditor {
18531869
* Unselect this editor.
18541870
*/
18551871
unselect() {
1872+
if (!this.isSelected) {
1873+
return;
1874+
}
1875+
this.isSelected = false;
18561876
this.#resizersDiv?.classList.add("hidden");
18571877
this.div?.classList.remove("selectedEditor");
18581878
if (this.div?.contains(document.activeElement)) {
@@ -1885,10 +1905,38 @@ class AnnotationEditor {
18851905
*/
18861906
enableEditing() {}
18871907

1908+
/**
1909+
* Check if the content of this editor can be changed.
1910+
* For example, a FreeText editor can be changed (the user can change the
1911+
* text), but a Stamp editor cannot.
1912+
* @returns {boolean}
1913+
*/
1914+
get canChangeContent() {
1915+
return false;
1916+
}
1917+
18881918
/**
18891919
* The editor is about to be edited.
18901920
*/
1891-
enterInEditMode() {}
1921+
enterInEditMode() {
1922+
if (!this.canChangeContent) {
1923+
return;
1924+
}
1925+
this.enableEditMode();
1926+
this.div.focus();
1927+
}
1928+
1929+
/**
1930+
* ondblclick callback.
1931+
* @param {MouseEvent} event
1932+
*/
1933+
dblclick(event) {
1934+
this.enterInEditMode();
1935+
this.parent.updateToolbar({
1936+
mode: this.constructor._editorType,
1937+
editId: this.id,
1938+
});
1939+
}
18921940

18931941
/**
18941942
* @returns {HTMLElement | null} the element requiring an alt text.

src/display/editor/freetext.js

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,7 @@ import {
2424
shadow,
2525
Util,
2626
} from "../../shared/util.js";
27-
import {
28-
AnnotationEditorUIManager,
29-
bindEvents,
30-
KeyboardManager,
31-
} from "./tools.js";
27+
import { AnnotationEditorUIManager, KeyboardManager } from "./tools.js";
3228
import { AnnotationEditor } from "./editor.js";
3329
import { FreeTextAnnotationElement } from "../annotation_layer.js";
3430

@@ -284,13 +280,10 @@ class FreeTextEditor extends AnnotationEditor {
284280

285281
/** @inheritdoc */
286282
enableEditMode() {
287-
if (this.isInEditMode()) {
288-
return;
283+
if (!super.enableEditMode()) {
284+
return false;
289285
}
290286

291-
this.parent.setEditingState(false);
292-
this.parent.updateToolbar(AnnotationEditorType.FREETEXT);
293-
super.enableEditMode();
294287
this.overlayDiv.classList.remove("enabled");
295288
this.editorDiv.contentEditable = true;
296289
this._isDraggable = false;
@@ -322,16 +315,16 @@ class FreeTextEditor extends AnnotationEditor {
322315
this.editorDiv.addEventListener("paste", this.editorDivPaste.bind(this), {
323316
signal,
324317
});
318+
319+
return true;
325320
}
326321

327322
/** @inheritdoc */
328323
disableEditMode() {
329-
if (!this.isInEditMode()) {
330-
return;
324+
if (!super.disableEditMode()) {
325+
return false;
331326
}
332327

333-
this.parent.setEditingState(true);
334-
super.disableEditMode();
335328
this.overlayDiv.classList.add("enabled");
336329
this.editorDiv.contentEditable = false;
337330
this.div.setAttribute("aria-activedescendant", this.#editorDivId);
@@ -349,6 +342,8 @@ class FreeTextEditor extends AnnotationEditor {
349342
// In case the blur callback hasn't been called.
350343
this.isEditing = false;
351344
this.parent.div.classList.add("freetextEditing");
345+
346+
return true;
352347
}
353348

354349
/** @inheritdoc */
@@ -498,18 +493,7 @@ class FreeTextEditor extends AnnotationEditor {
498493
this.editorDiv.focus();
499494
}
500495

501-
/**
502-
* ondblclick callback.
503-
* @param {MouseEvent} event
504-
*/
505-
dblclick(event) {
506-
this.enterInEditMode();
507-
}
508-
509-
/**
510-
* onkeydown callback.
511-
* @param {KeyboardEvent} event
512-
*/
496+
/** @inheritdoc */
513497
keydown(event) {
514498
if (event.target === this.div && event.key === "Enter") {
515499
this.enterInEditMode();
@@ -546,6 +530,11 @@ class FreeTextEditor extends AnnotationEditor {
546530
this.editorDiv.setAttribute("aria-multiline", true);
547531
}
548532

533+
/** @inheritdoc */
534+
get canChangeContent() {
535+
return true;
536+
}
537+
549538
/** @inheritdoc */
550539
render() {
551540
if (this.div) {
@@ -579,8 +568,6 @@ class FreeTextEditor extends AnnotationEditor {
579568
this.overlayDiv.classList.add("overlay", "enabled");
580569
this.div.append(this.overlayDiv);
581570

582-
bindEvents(this, this.div, ["dblclick", "keydown"]);
583-
584571
if (this._isCopy || this.annotationElementId) {
585572
// This editor was created in using copy (ctrl+c).
586573
const [parentWidth, parentHeight] = this.parentDimensions;

src/display/editor/stamp.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,10 @@ class StampEditor extends AnnotationEditor {
7171

7272
/** @inheritdoc */
7373
static paste(item, parent) {
74-
parent.pasteEditor(AnnotationEditorType.STAMP, {
75-
bitmapFile: item.getAsFile(),
76-
});
74+
parent.pasteEditor(
75+
{ mode: AnnotationEditorType.STAMP },
76+
{ bitmapFile: item.getAsFile() }
77+
);
7778
}
7879

7980
/** @inheritdoc */

src/display/editor/tools.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,7 +1711,7 @@ class AnnotationEditorUIManager {
17111711
}
17121712

17131713
for (const editor of this.#allEditors.values()) {
1714-
if (editor.annotationElementId === editId) {
1714+
if (editor.annotationElementId === editId || editor.id === editId) {
17151715
this.setSelected(editor);
17161716
editor.enterInEditMode();
17171717
} else {
@@ -1730,16 +1730,17 @@ class AnnotationEditorUIManager {
17301730

17311731
/**
17321732
* Update the toolbar if it's required to reflect the tool currently used.
1733+
* @param {Object} options
17331734
* @param {number} mode
17341735
* @returns {undefined}
17351736
*/
1736-
updateToolbar(mode) {
1737-
if (mode === this.#mode) {
1737+
updateToolbar(options) {
1738+
if (options.mode === this.#mode) {
17381739
return;
17391740
}
17401741
this._eventBus.dispatch("switchannotationeditormode", {
17411742
source: this,
1742-
mode,
1743+
...options,
17431744
});
17441745
}
17451746

test/integration/ink_editor_spec.mjs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,3 +1229,65 @@ describe("The pen-drawn shape must maintain correct curvature regardless of the
12291229
);
12301230
});
12311231
});
1232+
1233+
describe("Should switch from an editor and mode to others by double clicking", () => {
1234+
let pages;
1235+
1236+
beforeEach(async () => {
1237+
pages = await loadAndWait("empty.pdf", ".annotationEditorLayer");
1238+
});
1239+
1240+
afterEach(async () => {
1241+
await closePages(pages);
1242+
});
1243+
1244+
it("must check that the editor an the mode are correct", async () => {
1245+
await Promise.all(
1246+
pages.map(async ([browserName, page]) => {
1247+
await switchToInk(page);
1248+
1249+
const editorLayerRect = await getRect(page, ".annotationEditorLayer");
1250+
const drawStartX = editorLayerRect.x + 100;
1251+
const drawStartY = editorLayerRect.y + 100;
1252+
1253+
const inkSelector = getEditorSelector(0);
1254+
const clickHandle = await waitForPointerUp(page);
1255+
await page.mouse.move(drawStartX, drawStartY);
1256+
await page.mouse.down();
1257+
await page.mouse.move(drawStartX + 50, drawStartY + 50);
1258+
await page.mouse.up();
1259+
await awaitPromise(clickHandle);
1260+
await commit(page);
1261+
1262+
await switchToEditor("FreeText", page);
1263+
1264+
const freeTextSelector = getEditorSelector(1);
1265+
const data = "Hello PDF.js World !!";
1266+
await page.mouse.click(
1267+
editorLayerRect.x + 200,
1268+
editorLayerRect.y + 200
1269+
);
1270+
await page.waitForSelector(freeTextSelector, { visible: true });
1271+
await page.type(`${freeTextSelector} .internal`, data);
1272+
await page.keyboard.press("Escape");
1273+
await page.waitForSelector(
1274+
".freeTextEditor.selectedEditor .overlay.enabled"
1275+
);
1276+
1277+
await page.waitForSelector("#editorInkButton:not(.toggled)");
1278+
let modeChangedHandle = await waitForAnnotationModeChanged(page);
1279+
await selectEditor(page, inkSelector, 2);
1280+
await awaitPromise(modeChangedHandle);
1281+
await page.waitForSelector("#editorInkButton.toggled");
1282+
await waitForSelectedEditor(page, inkSelector);
1283+
1284+
await page.waitForSelector("#editorFreeTextButton:not(.toggled)");
1285+
modeChangedHandle = await waitForAnnotationModeChanged(page);
1286+
await selectEditor(page, freeTextSelector, 2);
1287+
await awaitPromise(modeChangedHandle);
1288+
await page.waitForSelector("#editorFreeTextButton.toggled");
1289+
await waitForSelectedEditor(page, freeTextSelector);
1290+
})
1291+
);
1292+
});
1293+
});

web/annotation_editor_layer_builder.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@
147147

148148
.annotationEditorLayer.disabled {
149149
pointer-events: none;
150+
151+
&.highlightEditing
152+
:is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) {
153+
pointer-events: auto;
154+
}
150155
}
151156

152157
.annotationEditorLayer.freetextEditing {

0 commit comments

Comments
 (0)