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