Merge pull request #15230 from calixteman/bug1781762
[Editor] Avoid editor creation/selection on right click (bug 1781762)
This commit is contained in:
commit
c9a4062c37
@ -21,8 +21,8 @@
|
|||||||
/** @typedef {import("../../web/interfaces").IL10n} IL10n */
|
/** @typedef {import("../../web/interfaces").IL10n} IL10n */
|
||||||
|
|
||||||
import { AnnotationEditorType, shadow } from "../../shared/util.js";
|
import { AnnotationEditorType, shadow } from "../../shared/util.js";
|
||||||
|
import { bindEvents, KeyboardManager } from "./tools.js";
|
||||||
import { binarySearchFirstItem } from "../display_utils.js";
|
import { binarySearchFirstItem } from "../display_utils.js";
|
||||||
import { bindEvents } from "./tools.js";
|
|
||||||
import { FreeTextEditor } from "./freetext.js";
|
import { FreeTextEditor } from "./freetext.js";
|
||||||
import { InkEditor } from "./ink.js";
|
import { InkEditor } from "./ink.js";
|
||||||
|
|
||||||
@ -577,6 +577,12 @@ class AnnotationEditorLayer {
|
|||||||
* @param {PointerEvent} event
|
* @param {PointerEvent} event
|
||||||
*/
|
*/
|
||||||
pointerup(event) {
|
pointerup(event) {
|
||||||
|
const isMac = KeyboardManager.platform.isMac;
|
||||||
|
if (event.button !== 0 || (event.ctrlKey && isMac)) {
|
||||||
|
// Don't create an editor on right click.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (event.target !== this.div) {
|
if (event.target !== this.div) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -594,6 +600,12 @@ class AnnotationEditorLayer {
|
|||||||
* @param {PointerEvent} event
|
* @param {PointerEvent} event
|
||||||
*/
|
*/
|
||||||
pointerdown(event) {
|
pointerdown(event) {
|
||||||
|
const isMac = KeyboardManager.platform.isMac;
|
||||||
|
if (event.button !== 0 || (event.ctrlKey && isMac)) {
|
||||||
|
// Do nothing on right click.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (event.target !== this.div) {
|
if (event.target !== this.div) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -253,6 +253,7 @@ class AnnotationEditor {
|
|||||||
if (event.button !== 0 || (event.ctrlKey && isMac)) {
|
if (event.button !== 0 || (event.ctrlKey && isMac)) {
|
||||||
// Avoid to focus this editor because of a non-left click.
|
// Avoid to focus this editor because of a non-left click.
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -217,6 +217,10 @@ class FreeTextEditor extends AnnotationEditor {
|
|||||||
|
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
enableEditMode() {
|
enableEditMode() {
|
||||||
|
if (this.isInEditMode()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.parent.setEditingState(false);
|
this.parent.setEditingState(false);
|
||||||
this.parent.updateToolbar(AnnotationEditorType.FREETEXT);
|
this.parent.updateToolbar(AnnotationEditorType.FREETEXT);
|
||||||
super.enableEditMode();
|
super.enableEditMode();
|
||||||
@ -230,6 +234,10 @@ class FreeTextEditor extends AnnotationEditor {
|
|||||||
|
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
disableEditMode() {
|
disableEditMode() {
|
||||||
|
if (!this.isInEditMode()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.parent.setEditingState(true);
|
this.parent.setEditingState(true);
|
||||||
super.disableEditMode();
|
super.disableEditMode();
|
||||||
this.overlayDiv.classList.add("enabled");
|
this.overlayDiv.classList.add("enabled");
|
||||||
@ -239,6 +247,10 @@ class FreeTextEditor extends AnnotationEditor {
|
|||||||
this.editorDiv.removeEventListener("focus", this.#boundEditorDivFocus);
|
this.editorDiv.removeEventListener("focus", this.#boundEditorDivFocus);
|
||||||
this.editorDiv.removeEventListener("blur", this.#boundEditorDivBlur);
|
this.editorDiv.removeEventListener("blur", this.#boundEditorDivBlur);
|
||||||
|
|
||||||
|
// On Chrome, the focus is given to <body> when contentEditable is set to
|
||||||
|
// false, hence we focus the div.
|
||||||
|
this.div.focus();
|
||||||
|
|
||||||
// In case the blur callback hasn't been called.
|
// In case the blur callback hasn't been called.
|
||||||
this.isEditing = false;
|
this.isEditing = false;
|
||||||
}
|
}
|
||||||
|
@ -244,6 +244,7 @@ class KeyboardManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
callback.bind(self)();
|
callback.bind(self)();
|
||||||
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ describe("Editor", () => {
|
|||||||
let pages;
|
let pages;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
pages = await loadAndWait("tracemonkey.pdf", ".annotationEditorLayer");
|
pages = await loadAndWait("aboutstacks.pdf", ".annotationEditorLayer");
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
@ -204,13 +204,13 @@ describe("Editor", () => {
|
|||||||
it("must check that aria-owns is correct", async () => {
|
it("must check that aria-owns is correct", async () => {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
pages.map(async ([browserName, page]) => {
|
pages.map(async ([browserName, page]) => {
|
||||||
const [adobeComRect, oldAriaOwns] = await page.$eval(
|
const [stacksRect, oldAriaOwns] = await page.$eval(
|
||||||
".textLayer",
|
".textLayer",
|
||||||
el => {
|
el => {
|
||||||
for (const span of el.querySelectorAll(
|
for (const span of el.querySelectorAll(
|
||||||
`span[role="presentation"]`
|
`span[role="presentation"]`
|
||||||
)) {
|
)) {
|
||||||
if (span.innerText.includes("adobe.com")) {
|
if (span.innerText.includes("Stacks are simple to create")) {
|
||||||
span.setAttribute("pdfjs", true);
|
span.setAttribute("pdfjs", true);
|
||||||
const { x, y, width, height } = span.getBoundingClientRect();
|
const { x, y, width, height } = span.getBoundingClientRect();
|
||||||
return [
|
return [
|
||||||
@ -227,21 +227,13 @@ describe("Editor", () => {
|
|||||||
|
|
||||||
const data = "Hello PDF.js World !!";
|
const data = "Hello PDF.js World !!";
|
||||||
await page.mouse.click(
|
await page.mouse.click(
|
||||||
adobeComRect.x + adobeComRect.width + 10,
|
stacksRect.x + stacksRect.width + 1,
|
||||||
adobeComRect.y + adobeComRect.height / 2
|
stacksRect.y + stacksRect.height / 2
|
||||||
);
|
);
|
||||||
await page.type(`${editorPrefix}5 .internal`, data);
|
await page.type(`${editorPrefix}5 .internal`, data);
|
||||||
|
|
||||||
const editorRect = await page.$eval(`${editorPrefix}5`, el => {
|
|
||||||
const { x, y, width, height } = el.getBoundingClientRect();
|
|
||||||
return { x, y, width, height };
|
|
||||||
});
|
|
||||||
|
|
||||||
// Commit.
|
// Commit.
|
||||||
await page.mouse.click(
|
await page.keyboard.press("Escape");
|
||||||
editorRect.x,
|
|
||||||
editorRect.y + 2 * editorRect.height
|
|
||||||
);
|
|
||||||
|
|
||||||
const ariaOwns = await page.$eval(".textLayer", el => {
|
const ariaOwns = await page.$eval(".textLayer", el => {
|
||||||
const span = el.querySelector(`span[pdfjs="true"]`);
|
const span = el.querySelector(`span[pdfjs="true"]`);
|
||||||
@ -254,13 +246,77 @@ describe("Editor", () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("must check that right click doesn't select", async () => {
|
||||||
|
await Promise.all(
|
||||||
|
pages.map(async ([browserName, page]) => {
|
||||||
|
const rect = await page.$eval(".annotationEditorLayer", el => {
|
||||||
|
const { x, y } = el.getBoundingClientRect();
|
||||||
|
return { x, y };
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.keyboard.down("Control");
|
||||||
|
await page.keyboard.press("a");
|
||||||
|
await page.keyboard.up("Control");
|
||||||
|
|
||||||
|
await page.keyboard.down("Control");
|
||||||
|
await page.keyboard.press("Backspace");
|
||||||
|
await page.keyboard.up("Control");
|
||||||
|
|
||||||
|
const data = "Hello PDF.js World !!";
|
||||||
|
await page.mouse.click(rect.x + 100, rect.y + 100);
|
||||||
|
await page.type(`${editorPrefix}6 .internal`, data);
|
||||||
|
|
||||||
|
const editorRect = await page.$eval(`${editorPrefix}6`, el => {
|
||||||
|
const { x, y, width, height } = el.getBoundingClientRect();
|
||||||
|
return { x, y, width, height };
|
||||||
|
});
|
||||||
|
|
||||||
|
// Commit.
|
||||||
|
await page.keyboard.press("Escape");
|
||||||
|
|
||||||
|
expect(await getSelectedEditors(page))
|
||||||
|
.withContext(`In ${browserName}`)
|
||||||
|
.toEqual([6]);
|
||||||
|
|
||||||
|
await page.keyboard.press("Escape");
|
||||||
|
expect(await getSelectedEditors(page))
|
||||||
|
.withContext(`In ${browserName}`)
|
||||||
|
.toEqual([]);
|
||||||
|
|
||||||
|
await page.mouse.click(
|
||||||
|
editorRect.x + editorRect.width / 2,
|
||||||
|
editorRect.y + editorRect.height / 2
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(await getSelectedEditors(page))
|
||||||
|
.withContext(`In ${browserName}`)
|
||||||
|
.toEqual([6]);
|
||||||
|
|
||||||
|
// Escape.
|
||||||
|
await page.keyboard.press("Escape");
|
||||||
|
|
||||||
|
expect(await getSelectedEditors(page))
|
||||||
|
.withContext(`In ${browserName}`)
|
||||||
|
.toEqual([]);
|
||||||
|
|
||||||
|
// TODO: uncomment that stuff once we've a way to dismiss
|
||||||
|
// the context menu.
|
||||||
|
/* await page.mouse.click(
|
||||||
|
editorRect.x + editorRect.width / 2,
|
||||||
|
editorRect.y + editorRect.height / 2,
|
||||||
|
{ button: "right" }
|
||||||
|
); */
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("FreeText (multiselection)", () => {
|
describe("FreeText (multiselection)", () => {
|
||||||
let pages;
|
let pages;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
pages = await loadAndWait("tracemonkey.pdf", ".annotationEditorLayer");
|
pages = await loadAndWait("aboutstacks.pdf", ".annotationEditorLayer");
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
|
@ -24,7 +24,7 @@ describe("Editor", () => {
|
|||||||
let pages;
|
let pages;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
pages = await loadAndWait("tracemonkey.pdf", ".annotationEditorLayer");
|
pages = await loadAndWait("aboutstacks.pdf", ".annotationEditorLayer");
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
@ -60,7 +60,7 @@ describe("Editor", () => {
|
|||||||
|
|
||||||
expect(await getSelectedEditors(page))
|
expect(await getSelectedEditors(page))
|
||||||
.withContext(`In ${browserName}`)
|
.withContext(`In ${browserName}`)
|
||||||
.toEqual([0, 2, 3]);
|
.toEqual([0, 1, 2]);
|
||||||
|
|
||||||
await page.keyboard.press("Backspace");
|
await page.keyboard.press("Backspace");
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user