Merge pull request #15786 from calixteman/15780_bis
[Editor] Add a very basic and incomplete workaround for issue #15780
This commit is contained in:
commit
feb6f5951c
@ -246,7 +246,7 @@ class AnnotationEditorLayer {
|
||||
this.attach(editor);
|
||||
editor.pageIndex = this.pageIndex;
|
||||
editor.parent?.detach(editor);
|
||||
editor.parent = this;
|
||||
editor.setParent(this);
|
||||
if (editor.div && editor.isAttachedToDOM) {
|
||||
editor.div.remove();
|
||||
this.div.append(editor.div);
|
||||
@ -521,8 +521,8 @@ class AnnotationEditorLayer {
|
||||
for (const editor of this.#editors.values()) {
|
||||
this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv);
|
||||
editor.isAttachedToDOM = false;
|
||||
editor.setParent(null);
|
||||
editor.div.remove();
|
||||
editor.parent = null;
|
||||
}
|
||||
this.div = null;
|
||||
this.#editors.clear();
|
||||
|
@ -68,6 +68,8 @@ class AnnotationEditor {
|
||||
this.rotation = this.parent.viewport.rotation;
|
||||
|
||||
this.isAttachedToDOM = false;
|
||||
|
||||
this._serialized = undefined;
|
||||
}
|
||||
|
||||
static get _defaultLineColor() {
|
||||
@ -78,6 +80,11 @@ class AnnotationEditor {
|
||||
);
|
||||
}
|
||||
|
||||
setParent(parent) {
|
||||
this._serialized = !parent ? this.serialize() : undefined;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* This editor will be behind the others.
|
||||
*/
|
||||
|
@ -478,6 +478,10 @@ class FreeTextEditor extends AnnotationEditor {
|
||||
|
||||
/** @inheritdoc */
|
||||
serialize() {
|
||||
if (this._serialized !== undefined) {
|
||||
return this._serialized;
|
||||
}
|
||||
|
||||
if (this.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
@ -1058,6 +1058,10 @@ class InkEditor extends AnnotationEditor {
|
||||
|
||||
/** @inheritdoc */
|
||||
serialize() {
|
||||
if (this._serialized !== undefined) {
|
||||
return this._serialized;
|
||||
}
|
||||
|
||||
if (this.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ const {
|
||||
getSelectedEditors,
|
||||
loadAndWait,
|
||||
waitForEvent,
|
||||
waitForSelectedEditor,
|
||||
waitForStorageEntries,
|
||||
} = require("./test_utils.js");
|
||||
|
||||
const copyPaste = async page => {
|
||||
@ -49,23 +51,6 @@ describe("Editor", () => {
|
||||
await closePages(pages);
|
||||
});
|
||||
|
||||
const waitForStorageEntries = async (page, nEntries) => {
|
||||
await page.waitForFunction(
|
||||
n =>
|
||||
window.PDFViewerApplication.pdfDocument.annotationStorage.size === n,
|
||||
{},
|
||||
nEntries
|
||||
);
|
||||
};
|
||||
|
||||
const waitForSelected = async (page, selector) => {
|
||||
await page.waitForFunction(
|
||||
sel => document.querySelector(sel).classList.contains("selectedEditor"),
|
||||
{},
|
||||
selector
|
||||
);
|
||||
};
|
||||
|
||||
it("must write a string in a FreeText editor", async () => {
|
||||
await Promise.all(
|
||||
pages.map(async ([browserName, page]) => {
|
||||
@ -98,7 +83,7 @@ describe("Editor", () => {
|
||||
editorRect.y + 2 * editorRect.height
|
||||
);
|
||||
|
||||
await waitForSelected(page, getEditorSelector(0));
|
||||
await waitForSelectedEditor(page, getEditorSelector(0));
|
||||
await waitForStorageEntries(page, 1);
|
||||
|
||||
const content = await page.$eval(getEditorSelector(0), el =>
|
||||
@ -123,7 +108,7 @@ describe("Editor", () => {
|
||||
editorRect.y + editorRect.height / 2
|
||||
);
|
||||
|
||||
await waitForSelected(page, getEditorSelector(0));
|
||||
await waitForSelectedEditor(page, getEditorSelector(0));
|
||||
await copyPaste(page);
|
||||
await waitForStorageEntries(page, 2);
|
||||
|
||||
@ -199,7 +184,7 @@ describe("Editor", () => {
|
||||
editorRect.y + editorRect.height / 2
|
||||
);
|
||||
|
||||
await waitForSelected(page, getEditorSelector(3));
|
||||
await waitForSelectedEditor(page, getEditorSelector(3));
|
||||
await copyPaste(page);
|
||||
|
||||
let hasEditor = await page.evaluate(sel => {
|
||||
@ -335,7 +320,7 @@ describe("Editor", () => {
|
||||
editorRect.y + editorRect.height / 2
|
||||
);
|
||||
|
||||
await waitForSelected(page, getEditorSelector(8));
|
||||
await waitForSelectedEditor(page, getEditorSelector(8));
|
||||
|
||||
expect(await getSelectedEditors(page))
|
||||
.withContext(`In ${browserName}`)
|
||||
@ -512,4 +497,110 @@ describe("Editor", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("FreeText (bugs)", () => {
|
||||
let pages;
|
||||
|
||||
beforeAll(async () => {
|
||||
pages = await loadAndWait("tracemonkey.pdf", ".annotationEditorLayer");
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await closePages(pages);
|
||||
});
|
||||
|
||||
it("must serialize invisible annotations", async () => {
|
||||
await Promise.all(
|
||||
pages.map(async ([browserName, page]) => {
|
||||
await page.click("#editorFreeText");
|
||||
let currentId = 0;
|
||||
const expected = [];
|
||||
const oneToFourteen = [...new Array(14).keys()].map(x => x + 1);
|
||||
|
||||
for (const pageNumber of oneToFourteen) {
|
||||
const pageSelector = `.page[data-page-number = "${pageNumber}"]`;
|
||||
|
||||
await page.evaluate(selector => {
|
||||
const element = window.document.querySelector(selector);
|
||||
element.scrollIntoView();
|
||||
}, pageSelector);
|
||||
|
||||
const annotationLayerSelector = `${pageSelector} > .annotationEditorLayer`;
|
||||
await page.waitForSelector(annotationLayerSelector, {
|
||||
visible: true,
|
||||
timeout: 0,
|
||||
});
|
||||
await page.waitForTimeout(50);
|
||||
if (![1, 14].includes(pageNumber)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const rect = await page.$eval(annotationLayerSelector, el => {
|
||||
// With Chrome something is wrong when serializing a DomRect,
|
||||
// hence we extract the values and just return them.
|
||||
const { x, y } = el.getBoundingClientRect();
|
||||
return { x, y };
|
||||
});
|
||||
|
||||
const data = `Hello PDF.js World !! on page ${pageNumber}`;
|
||||
expected.push(data);
|
||||
await page.mouse.click(rect.x + 100, rect.y + 100);
|
||||
await page.type(`${getEditorSelector(currentId)} .internal`, data);
|
||||
|
||||
const editorRect = await page.$eval(
|
||||
getEditorSelector(currentId),
|
||||
el => {
|
||||
const { x, y, width, height } = el.getBoundingClientRect();
|
||||
return {
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
// Commit.
|
||||
await page.mouse.click(
|
||||
editorRect.x,
|
||||
editorRect.y + 2 * editorRect.height
|
||||
);
|
||||
|
||||
await waitForSelectedEditor(page, getEditorSelector(currentId));
|
||||
await waitForStorageEntries(page, currentId + 1);
|
||||
|
||||
const content = await page.$eval(getEditorSelector(currentId), el =>
|
||||
el.innerText.trimEnd()
|
||||
);
|
||||
expect(content).withContext(`In ${browserName}`).toEqual(data);
|
||||
|
||||
currentId += 1;
|
||||
await page.waitForTimeout(10);
|
||||
}
|
||||
|
||||
const serialize = proprName =>
|
||||
page.evaluate(
|
||||
name =>
|
||||
[
|
||||
...window.PDFViewerApplication.pdfDocument.annotationStorage.serializable.values(),
|
||||
].map(x => x[name]),
|
||||
proprName
|
||||
);
|
||||
|
||||
expect(await serialize("value"))
|
||||
.withContext(`In ${browserName}`)
|
||||
.toEqual(expected);
|
||||
expect(await serialize("fontSize"))
|
||||
.withContext(`In ${browserName}`)
|
||||
.toEqual([10, 10]);
|
||||
expect(await serialize("color"))
|
||||
.withContext(`In ${browserName}`)
|
||||
.toEqual([
|
||||
[0, 0, 0],
|
||||
[0, 0, 0],
|
||||
]);
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -100,3 +100,21 @@ async function waitForEvent(page, eventName, timeout = 30000) {
|
||||
]);
|
||||
}
|
||||
exports.waitForEvent = waitForEvent;
|
||||
|
||||
const waitForStorageEntries = async (page, nEntries) => {
|
||||
await page.waitForFunction(
|
||||
n => window.PDFViewerApplication.pdfDocument.annotationStorage.size === n,
|
||||
{},
|
||||
nEntries
|
||||
);
|
||||
};
|
||||
exports.waitForStorageEntries = waitForStorageEntries;
|
||||
|
||||
const waitForSelectedEditor = async (page, selector) => {
|
||||
await page.waitForFunction(
|
||||
sel => document.querySelector(sel).classList.contains("selectedEditor"),
|
||||
{},
|
||||
selector
|
||||
);
|
||||
};
|
||||
exports.waitForSelectedEditor = waitForSelectedEditor;
|
||||
|
Loading…
Reference in New Issue
Block a user