-
Notifications
You must be signed in to change notification settings - Fork 10.7k
Move editToolbar and fix overlapping annotations with it #21723
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ | |
| import { | ||
| awaitPromise, | ||
| closePages, | ||
| createFreeTextEditor, | ||
| FSI, | ||
| getAnnotationSelector, | ||
| getEditorSelector, | ||
|
|
@@ -56,6 +57,8 @@ const selectAll = selectEditors.bind(null, "highlight"); | |
|
|
||
| const switchToHighlight = switchToEditor.bind(null, "Highlight"); | ||
|
|
||
| const switchToFreeText = switchToEditor.bind(null, "FreeText"); | ||
|
|
||
| describe("Highlight Editor", () => { | ||
| describe("Editor must be removed without exception", () => { | ||
| let pages; | ||
|
|
@@ -1414,8 +1417,8 @@ describe("Highlight Editor", () => { | |
| const y = rect.y + rect.height / 2; | ||
| await page.mouse.click(x, y, { count: 2, delay: 100 }); | ||
|
|
||
| await page.waitForSelector(".textLayer .highlightButton"); | ||
| await page.click(".textLayer .highlightButton"); | ||
| await page.waitForSelector(".highlightButton"); | ||
| await page.click(".highlightButton"); | ||
|
|
||
| await page.waitForSelector(getEditorSelector(editorId)); | ||
| const usedColor = await page.evaluate(() => { | ||
|
|
@@ -1470,7 +1473,7 @@ describe("Highlight Editor", () => { | |
| delay: 100, | ||
| }); | ||
|
|
||
| const toolbarRect = await getRect(page, ".textLayer .editToolbar"); | ||
| const toolbarRect = await getRect(page, ".editToolbar"); | ||
|
|
||
| // In RTL, the left edge of the toolbar is aligned on the left edge | ||
| // of the selection (bug 2060032). | ||
|
|
@@ -1891,8 +1894,8 @@ describe("Highlight Editor", () => { | |
| const y = rect.y + rect.height / 2; | ||
| await page.mouse.click(x, y, { count: 3, delay: 100 }); | ||
|
|
||
| await page.waitForSelector(".textLayer .highlightButton"); | ||
| await page.click(".textLayer .highlightButton"); | ||
| await page.waitForSelector(".highlightButton"); | ||
| await page.click(".highlightButton"); | ||
|
|
||
| await page.waitForSelector(getEditorSelector(0)); | ||
| const usedColor = await page.evaluate(() => { | ||
|
|
@@ -2909,4 +2912,131 @@ describe("Highlight Editor", () => { | |
| }); | ||
| }); | ||
| }); | ||
|
|
||
| describe("editToolbar is rendering over annotations", () => { | ||
| let pages; | ||
|
|
||
| beforeEach(async () => { | ||
| pages = await loadAndWait( | ||
| "toolbar-overlap-with-annotations.pdf", | ||
| ".annotationEditorLayer", | ||
| 120 | ||
| ); | ||
| }); | ||
|
|
||
| afterEach(async () => { | ||
| await closePages(pages); | ||
| }); | ||
|
|
||
| it("must check that the edit toolbar is rendered above link annotations", async () => { | ||
| await Promise.all( | ||
| pages.map(async ([browserName, page]) => { | ||
| await page.waitForSelector( | ||
| `.page[data-page-number = "1"] .textLayer .endOfContent` | ||
| ); | ||
|
|
||
| const linkSelector = `a[href="https://github.com/mozilla/pdf.js"]`; | ||
| const linkRect = await getRect(page, linkSelector); | ||
|
|
||
| const topElementId = await page.evaluate( | ||
| (px, py) => document.elementFromPoint(px, py)?.id || null, | ||
| linkRect.x, | ||
| linkRect.y | ||
| ); | ||
| expect(topElementId) | ||
| .withContext(`In ${browserName}`) | ||
| .toEqual("pdfjs_internal_id_14R"); | ||
|
|
||
| // Double click on "A:" to show the edit toolbar. | ||
| const firstRect = await getSpanRectFromText(page, 1, "A:"); | ||
| await page.mouse.click(firstRect.x, firstRect.y, { | ||
| count: 2, | ||
| delay: 100, | ||
| }); | ||
|
|
||
| const highlightButtonSelector = `.page[data-page-number = "1"] .editToolbar button.highlightButton`; | ||
| await page.waitForSelector(highlightButtonSelector, { | ||
| visible: true, | ||
| }); | ||
|
|
||
| const topElementClass = await page.evaluate( | ||
| (px, py) => document.elementFromPoint(px, py)?.className || null, | ||
| linkRect.x, | ||
| linkRect.y | ||
| ); | ||
| expect(topElementClass) | ||
| .withContext(`In ${browserName}`) | ||
| .toContain("highlightButton"); | ||
| }) | ||
| ); | ||
| }); | ||
|
|
||
| it("must check that the edit toolbar is rendered above text annotations", async () => { | ||
| await Promise.all( | ||
| pages.map(async ([browserName, page]) => { | ||
| await switchToFreeText(page); | ||
|
|
||
| const myText = await getSpanRectFromText(page, 1, "My text"); | ||
| // "CHECK" is roughly 50px wide at the default font size and | ||
| // is roughly aligned with the end of "My text". | ||
| const editorSelector = await createFreeTextEditor({ | ||
| page, | ||
| x: myText.x + myText.width / 2, | ||
| y: myText.y + myText.height + 20, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a particular reason to not just have
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, because About the test above ("must check that the edit toolbar is rendered above link annotations"), I corrected it to just check: document.elementFromPoint(px, py)?.id || null,
linkRect.x,
linkRect.y
);because that's where I later check for the |
||
| data: "CHECK", | ||
| }); | ||
|
|
||
| const freeTextRect = await getRect(page, editorSelector); | ||
| const freeTextTopElement = await page.evaluate( | ||
| (px, py) => | ||
| document.elementFromPoint(px, py)?.getAttribute("data-l10n-id") || | ||
| null, | ||
| freeTextRect.x + freeTextRect.width / 2, | ||
| freeTextRect.y + freeTextRect.height / 2 | ||
| ); | ||
| expect(freeTextTopElement) | ||
| .withContext(`In ${browserName}`) | ||
| .toEqual("pdfjs-free-text2"); | ||
|
|
||
| // Close the text editor. | ||
| await switchToFreeText(page, /* disable */ true); | ||
|
|
||
| // Double click on "myText" to show the edit toolbar. | ||
| await page.mouse.click( | ||
| myText.x + myText.width / 2, | ||
| myText.y + myText.height / 2, | ||
| { count: 2, delay: 100 } | ||
| ); | ||
|
|
||
| const toolbarSelector = `.page[data-page-number = "1"] .editToolbar:has(button.highlightButton)`; | ||
| const highlightButtonSelector = `${toolbarSelector} button.highlightButton`; | ||
| await page.waitForSelector(highlightButtonSelector, { | ||
| visible: true, | ||
| }); | ||
|
|
||
| let topElement = await page.evaluate( | ||
| (px, py) => document.elementFromPoint(px, py)?.className || null, | ||
| freeTextRect.x + freeTextRect.width / 2, | ||
| freeTextRect.y + freeTextRect.height / 2 | ||
| ); | ||
| expect(topElement) | ||
| .withContext(`In ${browserName}`) | ||
| .toContain("highlightButton"); | ||
|
|
||
| // Re-open the text editor without dismissing the edit toolbar, | ||
| // so both are present on the page at the same time. | ||
| await switchToFreeText(page); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have tried this in the browser and in the integration test itself, but only enabling free text mode doesn't cause a second toolbar to appear: the annotation actually has to be clicked. It therefore looks like the assertion below passes "by accident" because the highlight button state from the previous assertion didn't change?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A second toolbar doesn't need to appear because the first one is already there. When switching to free-text, the toolbar is already opened from double-clicking on "My Text". The test checks which element is rendered above with |
||
|
|
||
| topElement = await page.evaluate( | ||
| (px, py) => document.elementFromPoint(px, py)?.className || null, | ||
| freeTextRect.x + freeTextRect.width / 2, | ||
| freeTextRect.y + freeTextRect.height / 2 | ||
| ); | ||
| expect(topElement) | ||
| .withContext(`In ${browserName}`) | ||
| .toContain("highlightButton"); | ||
| }) | ||
| ); | ||
| }); | ||
| }); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not for this PR, but in a follow-up we might want to consider moving the floating toolbar tests into their own spec. It feels a bit odd conceptually to have it here because we don't create actual highlight annotations in these tests, nor is the floating toolbar only for highlight annotations as comments can also be created with it now. (It originally used to only be for highlighting, and the preference name is also called that, but I think that predates the commenting addition.)
@calixteman What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.