diff --git a/test/integration/stamp_editor_spec.mjs b/test/integration/stamp_editor_spec.mjs index 0819550215d2e..a632963a4f18d 100644 --- a/test/integration/stamp_editor_spec.mjs +++ b/test/integration/stamp_editor_spec.mjs @@ -30,6 +30,7 @@ import { scrollIntoView, serializeBitmapDimensions, waitForAnnotationEditorLayer, + waitForEntryInStorage, waitForSelectedEditor, waitForSerialized, waitForStorageEntries, @@ -698,4 +699,67 @@ describe("Stamp Editor", () => { ); }); }); + + describe("Resize a stamp", () => { + let pages; + + beforeAll(async () => { + pages = await loadAndWait("empty.pdf", ".annotationEditorLayer"); + }); + + afterAll(async () => { + await closePages(pages); + }); + + it("must check that a resized stamp has its canvas at the right position", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + await page.click("#editorStamp"); + await page.waitForSelector(".annotationEditorLayer.stampEditing"); + + await copyImage(page, "../images/firefox_logo.png", 0); + await page.waitForSelector(getEditorSelector(0)); + await waitForSerialized(page, 1); + + const serializedRect = await getFirstSerialized(page, x => x.rect); + const rect = await page.$eval(".resizer.bottomRight", el => { + // With Chrome something is wrong when serializing a DomRect, + // hence we extract the values and just return them. + const { x, y, width, height } = el.getBoundingClientRect(); + return { x, y, width, height }; + }); + const centerX = rect.x + rect.width / 2; + const centerY = rect.y + rect.height / 2; + + await page.mouse.move(centerX, centerY); + await page.mouse.down(); + await page.mouse.move(centerX - 500, centerY - 500); + await page.mouse.up(); + + await waitForEntryInStorage( + page, + "rect", + serializedRect, + (x, y) => x !== y + ); + + const canvasRect = await page.$eval( + `${getEditorSelector(0)} canvas`, + el => { + const { x, y, width, height } = el.getBoundingClientRect(); + return [x, y, width, height]; + } + ); + const stampRect = await page.$eval(getEditorSelector(0), el => { + const { x, y, width, height } = el.getBoundingClientRect(); + return [x, y, width, height]; + }); + + expect( + canvasRect.every((x, i) => Math.abs(x - stampRect[i]) <= 10) + ).toBeTrue(); + }) + ); + }); + }); }); diff --git a/test/integration/test_utils.mjs b/test/integration/test_utils.mjs index 71983fa3d904c..f1ecf7cc4f2c7 100644 --- a/test/integration/test_utils.mjs +++ b/test/integration/test_utils.mjs @@ -291,16 +291,18 @@ function getAnnotationStorage(page) { ); } -function waitForEntryInStorage(page, key, value) { +function waitForEntryInStorage(page, key, value, checker = (x, y) => x === y) { return page.waitForFunction( - (k, v) => { + (k, v, c) => { const { map } = window.PDFViewerApplication.pdfDocument.annotationStorage.serializable; - return map && JSON.stringify(map.get(k)) === v; + // eslint-disable-next-line no-eval + return map && eval(`(${c})`)(JSON.stringify(map.get(k)), v); }, {}, key, - JSON.stringify(value) + JSON.stringify(value), + checker.toString() ); } diff --git a/web/annotation_editor_layer_builder.css b/web/annotation_editor_layer_builder.css index eb0ea08856daf..9761714a509b7 100644 --- a/web/annotation_editor_layer_builder.css +++ b/web/annotation_editor_layer_builder.css @@ -502,11 +502,13 @@ .annotationEditorLayer .stampEditor { width: auto; height: auto; -} -.annotationEditorLayer .stampEditor canvas { - width: 100%; - height: 100%; + canvas { + position: absolute; + width: 100%; + height: 100%; + margin: 0; + } } .annotationEditorLayer { diff --git a/web/pdf_viewer.css b/web/pdf_viewer.css index bbd6ca97b7a51..fb91352ae9fae 100644 --- a/web/pdf_viewer.css +++ b/web/pdf_viewer.css @@ -69,12 +69,30 @@ @media screen and (forced-colors: active) { --hcm-highlight-filter: invert(100%); } -} -.pdfViewer .canvasWrapper { - overflow: hidden; - width: 100%; - height: 100%; + .canvasWrapper { + overflow: hidden; + width: 100%; + height: 100%; + + canvas { + margin: 0; + display: block; + + &[hidden] { + display: none; + } + + &[zooming] { + width: 100%; + height: 100%; + } + + .structTree { + contain: strict; + } + } + } } .pdfViewer .page { @@ -153,24 +171,6 @@ } /*#endif*/ -.pdfViewer .page canvas { - margin: 0; - display: block; -} - -.pdfViewer .page canvas .structTree { - contain: strict; -} - -.pdfViewer .page canvas[hidden] { - display: none; -} - -.pdfViewer .page canvas[zooming] { - width: 100%; - height: 100%; -} - .pdfViewer .page.loadingIcon::after { position: absolute; top: 0;