Merge pull request #16916 from calixteman/parent_in_struct_tree

[Editor] Add the parent tag id (if any) to the serialized editors (bug 1845087)
This commit is contained in:
calixteman 2023-09-08 16:24:47 +02:00 committed by GitHub
commit b903b3030a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 69 additions and 8 deletions

View File

@ -409,7 +409,7 @@ class AnnotationEditorLayer {
}, 0); }, 0);
} }
this.#accessibilityManager?.moveElementInDOM( editor._structTreeParentId = this.#accessibilityManager?.moveElementInDOM(
this.div, this.div,
editor.div, editor.div,
editor.contentDiv, editor.contentDiv,

View File

@ -80,6 +80,7 @@ class AnnotationEditor {
this.annotationElementId = null; this.annotationElementId = null;
this._willKeepAspectRatio = false; this._willKeepAspectRatio = false;
this._initialOptions.isCentered = parameters.isCentered; this._initialOptions.isCentered = parameters.isCentered;
this._structTreeParentId = null;
const { const {
rotation, rotation,

View File

@ -735,6 +735,7 @@ class FreeTextEditor extends AnnotationEditor {
pageIndex: this.pageIndex, pageIndex: this.pageIndex,
rect, rect,
rotation: this.rotation, rotation: this.rotation,
structTreeParentId: this._structTreeParentId,
}; };
if (isForCopying) { if (isForCopying) {

View File

@ -1199,6 +1199,7 @@ class InkEditor extends AnnotationEditor {
pageIndex: this.pageIndex, pageIndex: this.pageIndex,
rect, rect,
rotation: this.rotation, rotation: this.rotation,
structTreeParentId: this._structTreeParentId,
}; };
} }
} }

View File

@ -506,6 +506,7 @@ class StampEditor extends AnnotationEditor {
rect: this.getRect(0, 0), rect: this.getRect(0, 0),
rotation: this.rotation, rotation: this.rotation,
isSvg: this.#isSvg, isSvg: this.#isSvg,
structTreeParentId: this._structTreeParentId,
}; };
if (isForCopying) { if (isForCopying) {

View File

@ -2429,4 +2429,53 @@ describe("FreeText Editor", () => {
); );
}); });
}); });
describe("FreeText accessibility", () => {
let pages;
beforeAll(async () => {
pages = await loadAndWait("bug1823296.pdf", ".annotationEditorLayer");
});
afterAll(async () => {
await closePages(pages);
});
it("must check that the parent structTree id is correct", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
await page.click("#editorFreeText");
const parentId = "p3R_mc8";
const rect = await page.evaluate(id => {
const parent = document.getElementById(id);
let span = null;
for (const child of parent.childNodes) {
if (child.innerText === "000.[5]") {
span = child;
break;
}
}
const { x, y, width, height } = span.getBoundingClientRect();
return { x, y, width, height };
}, parentId);
await page.mouse.click(
rect.x + rect.width + 5,
rect.y + rect.height / 2
);
await page.waitForTimeout(10);
await page.type(`${getEditorSelector(0)} .internal`, "Hello Wolrd");
// Commit.
await page.keyboard.press("Escape");
await page.waitForTimeout(10);
await waitForStorageEntries(page, 1);
const id = await getFirstSerialized(page, x => x.structTreeParentId);
expect(id).withContext(`In ${browserName}`).toEqual(parentId);
})
);
});
});
}); });

View File

@ -179,17 +179,18 @@ class TextAccessibilityManager {
* in order to correctly position this editor in the text flow. * in order to correctly position this editor in the text flow.
* @param {HTMLElement} element * @param {HTMLElement} element
* @param {boolean} isRemovable * @param {boolean} isRemovable
* @returns {string|null} The id in the struct tree if any.
*/ */
addPointerInTextLayer(element, isRemovable) { addPointerInTextLayer(element, isRemovable) {
const { id } = element; const { id } = element;
if (!id) { if (!id) {
return; return null;
} }
if (!this.#enabled) { if (!this.#enabled) {
// The text layer needs to be there, so we postpone the association. // The text layer needs to be there, so we postpone the association.
this.#waitingElements.set(element, isRemovable); this.#waitingElements.set(element, isRemovable);
return; return null;
} }
if (isRemovable) { if (isRemovable) {
@ -198,7 +199,7 @@ class TextAccessibilityManager {
const children = this.#textChildren; const children = this.#textChildren;
if (!children || children.length === 0) { if (!children || children.length === 0) {
return; return null;
} }
const index = binarySearchFirstItem( const index = binarySearchFirstItem(
@ -208,20 +209,25 @@ class TextAccessibilityManager {
); );
const nodeIndex = Math.max(0, index - 1); const nodeIndex = Math.max(0, index - 1);
this.#addIdToAriaOwns(id, children[nodeIndex]); const child = children[nodeIndex];
this.#addIdToAriaOwns(id, child);
this.#textNodes.set(id, nodeIndex); this.#textNodes.set(id, nodeIndex);
const parent = child.parentNode;
return parent?.classList.contains("markedContent") ? parent.id : null;
} }
/** /**
* Move a div in the DOM in order to respect the visual order. * Move a div in the DOM in order to respect the visual order.
* @param {HTMLDivElement} element * @param {HTMLDivElement} element
* @returns {string|null} The id in the struct tree if any.
*/ */
moveElementInDOM(container, element, contentElement, isRemovable) { moveElementInDOM(container, element, contentElement, isRemovable) {
this.addPointerInTextLayer(contentElement, isRemovable); const id = this.addPointerInTextLayer(contentElement, isRemovable);
if (!container.hasChildNodes()) { if (!container.hasChildNodes()) {
container.append(element); container.append(element);
return; return id;
} }
const children = Array.from(container.childNodes).filter( const children = Array.from(container.childNodes).filter(
@ -229,7 +235,7 @@ class TextAccessibilityManager {
); );
if (children.length === 0) { if (children.length === 0) {
return; return id;
} }
const elementToCompare = contentElement || element; const elementToCompare = contentElement || element;
@ -247,6 +253,8 @@ class TextAccessibilityManager {
} else { } else {
children[index - 1].after(element); children[index - 1].after(element);
} }
return id;
} }
} }