Skip to content

Commit

Permalink
Merge pull request #16916 from calixteman/parent_in_struct_tree
Browse files Browse the repository at this point in the history
[Editor] Add the parent tag id (if any) to the serialized editors (bug 1845087)
  • Loading branch information
calixteman authored Sep 8, 2023
2 parents 3e32d87 + c6f7e72 commit b903b30
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/display/editor/annotation_editor_layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ class AnnotationEditorLayer {
}, 0);
}

this.#accessibilityManager?.moveElementInDOM(
editor._structTreeParentId = this.#accessibilityManager?.moveElementInDOM(
this.div,
editor.div,
editor.contentDiv,
Expand Down
1 change: 1 addition & 0 deletions src/display/editor/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class AnnotationEditor {
this.annotationElementId = null;
this._willKeepAspectRatio = false;
this._initialOptions.isCentered = parameters.isCentered;
this._structTreeParentId = null;

const {
rotation,
Expand Down
1 change: 1 addition & 0 deletions src/display/editor/freetext.js
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ class FreeTextEditor extends AnnotationEditor {
pageIndex: this.pageIndex,
rect,
rotation: this.rotation,
structTreeParentId: this._structTreeParentId,
};

if (isForCopying) {
Expand Down
1 change: 1 addition & 0 deletions src/display/editor/ink.js
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,7 @@ class InkEditor extends AnnotationEditor {
pageIndex: this.pageIndex,
rect,
rotation: this.rotation,
structTreeParentId: this._structTreeParentId,
};
}
}
Expand Down
1 change: 1 addition & 0 deletions src/display/editor/stamp.js
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ class StampEditor extends AnnotationEditor {
rect: this.getRect(0, 0),
rotation: this.rotation,
isSvg: this.#isSvg,
structTreeParentId: this._structTreeParentId,
};

if (isForCopying) {
Expand Down
49 changes: 49 additions & 0 deletions test/integration/freetext_editor_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
})
);
});
});
});
22 changes: 15 additions & 7 deletions web/text_accessibility.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,17 +179,18 @@ class TextAccessibilityManager {
* in order to correctly position this editor in the text flow.
* @param {HTMLElement} element
* @param {boolean} isRemovable
* @returns {string|null} The id in the struct tree if any.
*/
addPointerInTextLayer(element, isRemovable) {
const { id } = element;
if (!id) {
return;
return null;
}

if (!this.#enabled) {
// The text layer needs to be there, so we postpone the association.
this.#waitingElements.set(element, isRemovable);
return;
return null;
}

if (isRemovable) {
Expand All @@ -198,7 +199,7 @@ class TextAccessibilityManager {

const children = this.#textChildren;
if (!children || children.length === 0) {
return;
return null;
}

const index = binarySearchFirstItem(
Expand All @@ -208,28 +209,33 @@ class TextAccessibilityManager {
);

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);

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.
* @param {HTMLDivElement} element
* @returns {string|null} The id in the struct tree if any.
*/
moveElementInDOM(container, element, contentElement, isRemovable) {
this.addPointerInTextLayer(contentElement, isRemovable);
const id = this.addPointerInTextLayer(contentElement, isRemovable);

if (!container.hasChildNodes()) {
container.append(element);
return;
return id;
}

const children = Array.from(container.childNodes).filter(
node => node !== element
);

if (children.length === 0) {
return;
return id;
}

const elementToCompare = contentElement || element;
Expand All @@ -247,6 +253,8 @@ class TextAccessibilityManager {
} else {
children[index - 1].after(element);
}

return id;
}
}

Expand Down

0 comments on commit b903b30

Please sign in to comment.