From 0392feaee4f2101947fa022c90ac1299d7079a0a Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Mon, 8 Jan 2024 18:33:36 +0100 Subject: [PATCH] Remove terminal white spaces when extracting text from annotation appearances --- src/core/annotation.js | 8 +++--- test/integration-boot.mjs | 1 + test/integration/text_field_spec.mjs | 39 +++++++++++++++++++++++++++ test/pdfs/.gitignore | 1 + test/pdfs/file_pdfjs_form.pdf | Bin 0 -> 8586 bytes 5 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 test/integration/text_field_spec.mjs create mode 100755 test/pdfs/file_pdfjs_form.pdf diff --git a/src/core/annotation.js b/src/core/annotation.js index 6e1bc1147..6307dd36f 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -1195,7 +1195,7 @@ class Annotation { firstPosition ||= item.transform.slice(-2); buffer.push(item.str); if (item.hasEOL) { - text.push(buffer.join("")); + text.push(buffer.join("").trimEnd()); buffer.length = 0; } } @@ -1214,7 +1214,7 @@ class Annotation { this.reset(); if (buffer.length) { - text.push(buffer.join("")); + text.push(buffer.join("").trimEnd()); } if (text.length > 1 || text[0]) { @@ -3788,7 +3788,9 @@ class FreeTextAnnotation extends MarkupAnnotation { this.data.defaultAppearanceData.fontSize ||= 10; const { fontColor, fontSize } = this.data.defaultAppearanceData; if (this._contents.str) { - this.data.textContent = this._contents.str.split(/\r\n?|\n/); + this.data.textContent = this._contents.str + .split(/\r\n?|\n/) + .map(line => line.trimEnd()); const { coords, bbox, matrix } = FakeUnicodeFont.getFirstPositionInfo( this.rectangle, this.rotation, diff --git a/test/integration-boot.mjs b/test/integration-boot.mjs index 6d7dad4a5..f50ece885 100644 --- a/test/integration-boot.mjs +++ b/test/integration-boot.mjs @@ -33,6 +33,7 @@ async function runTests(results) { "ink_editor_spec.mjs", "scripting_spec.mjs", "stamp_editor_spec.mjs", + "text_field_spec.mjs", ], }); diff --git a/test/integration/text_field_spec.mjs b/test/integration/text_field_spec.mjs new file mode 100644 index 000000000..aa8fd8725 --- /dev/null +++ b/test/integration/text_field_spec.mjs @@ -0,0 +1,39 @@ +/* Copyright 2024 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { closePages, getSelector, loadAndWait } from "./test_utils.mjs"; + +describe("Text field", () => { + describe("Empty text field", () => { + let pages; + + beforeAll(async () => { + pages = await loadAndWait("file_pdfjs_form.pdf", getSelector("7R")); + }); + + afterAll(async () => { + await closePages(pages); + }); + + it("must check that the field is empty although its appearance contains a white space", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + const text = await page.$eval(getSelector("7R"), el => el.value); + expect(text).withContext(`In ${browserName}`).toEqual(""); + }) + ); + }); + }); +}); diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 1387f44ba..b4c5725b5 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -623,3 +623,4 @@ !bug1872721.pdf !bug1871353.pdf !bug1871353.1.pdf +!file_pdfjs_form.pdf diff --git a/test/pdfs/file_pdfjs_form.pdf b/test/pdfs/file_pdfjs_form.pdf new file mode 100755 index 0000000000000000000000000000000000000000..c6eff988a6793a6bc9812a840b1b8a0c75a89d35 GIT binary patch literal 8586 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 M-IOUa+mdzv0S+fc9smFU literal 0 HcmV?d00001