-
Notifications
You must be signed in to change notification settings - Fork 10k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Annotations] Add some aria-owns in the text layer to link to annotations (bug 1780375) #15237
Conversation
@jcsteh, @MReschenberg, your feedback will be appreciated. |
Please note: I'll hold off on reviewing this until feedback has been provided from the a11y-devs, as was requested above, on the off chance that the implementation changes significantly. Furthermore, it'd also be a really good idea to create a new release first given the size/scope of these changes. (Which hopefully happens soon, since we agreed to try and have a new release at the end of each month.) |
Indeed, I'll make a new release tomorrow since it's the end of the month. |
I took a look at this, but I wasn't able to see the annotations with a screen reader. Some questions:
Also, how will this interact with tagged PDF? I don't fully understand how the text and structure layers fit together, but I know tagged PDF (structure) uses aria-owns as well. |
When the text annotations are added to the DOM, do they have C SS display: none and/or visibility: hidden? That will prevent them from being exposed to a11y. One other thing I've just noticed is that when a text editor is dismissed, the editor still has role="textbox". That should be removed when contentEditable is disabled. I guess that needs to be handled elsewhere, though? |
web/pdf_page_view.js
Outdated
@@ -807,6 +812,7 @@ class PDFPageView { | |||
} | |||
this.eventBus._off("textlayerrendered", this._onTextLayerRendered); | |||
this._onTextLayerRendered = null; | |||
this._accessibilityManager.onTextLayerRendered(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most likely this line, or rather its placement, explains the problem mentioned in #15237 (comment).
By placing this line here you've limited this functionality to only documents with structureTree-information, which I'm guessing isn't actually intended?
If you actually want to call this method unconditionally, you'll need to pass in the AccessibilityManager
-instance to the TextLayerBuilder
-instance and invoke that method there instead (similar to how the TextHighlighter
-instance is handled).
Basically, I'm guessing that you want to call it after the following line instead:
pdf.js/web/text_layer_builder.js
Line 116 in 803e7af
this.highlighter?.enable(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a look at this, but I wasn't able to see the annotations with a screen reader. Some questions:
1. Perhaps I'm not understanding how to commit/save annotations to a document. I made a text annotation, dismissed the editor with control+enter, saved the PDF with control+s and then opened the saved PDF in the modified pdf.js. Is there anything else I need to do? I'm pretty sure I can see the annotation with OCR, but it's hard to be certain. 2. Is there anything else I need to do when switching pdf.js branches apart from npm install and gulp server?
It's exactly what you've to do.
3. Are you able to see the annotations in the Firefox Accessibility Inspector?
Also, how will this interact with tagged PDF? I don't fully understand how the text and structure layers fit together, but I know tagged PDF (structure) uses aria-owns as well.
I fixed the bug mentioned by Jonas and it should be fine now: I can see it correctly in the inspector.
Anyway, for now the content of the annotation is still not available: I just added an aria-owns
between a span in the text layer and an annotation in the annotation layer. So it should be useful to see at least the annotations which don't have any content like a text field or a checkbox.
I've a wip to make the text content of a FreeText annotation in its HTML counterpart.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anyway, for now the content of the annotation is still not available: I just added an aria-owns between a span in the text layer and an annotation in the annotation layer. So it should be useful to see at least the annotations which don't have any content like a text field or a checkbox.
I'm not really sure how to test this/provide feedback if text annotations aren't fully exposed yet, as I can't create other kinds of annotations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once this PR is merged (it should be in 30 minutes):
#15267
it should be a way easier to test this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jcsteh, I merged the other PR and I rebased this one, so we should be good now.
Sorry for the inconvenience: I should have written the second patch in first.
a3b02f5
to
0e13a95
Compare
…bug 1780375) An annotation doesn't have to be in the text flow, hence it's likely a bad idea to insert its text in the text layer. But the text must be visible from a screen reader point of view so it must somewhere in the DOM. So with this patch, the text from a FreeText annotation is extracted and added in a div in its HTML counterpart, and with the patch mozilla#15237 the text should be visible and positioned relatively to the text flow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving a few basic comments about the overall shape/structure of the new AccessibilityManager
-class, since I don't expect the a11y-review to really change that.
src/display/accessibility.js
Outdated
* annotations in the annotation layer. The goal is to help to know | ||
* where the annotations are in the text flow. | ||
*/ | ||
class AccessibilityManager { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this class perhaps be named TextAccessibilityManager
instead, and the filename changed to text_accessibility.js
, to more clearly indicate what it does?
In any case, given how this is now initialized and used, I think this file should be moved into the web/
-folder instead.
src/display/accessibility.js
Outdated
* - to reorder element in the DOM with respect to the visual order; | ||
* - make a link in using aria-owns between spans in the text layer and | ||
* annotations in the annotation layer. The goal is to help to know | ||
* where the annotations are in the text flow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nits:
* - to reorder element in the DOM with respect to the visual order; | |
* - make a link in using aria-owns between spans in the text layer and | |
* annotations in the annotation layer. The goal is to help to know | |
* where the annotations are in the text flow. | |
* - to reorder elements in the DOM with respect to the visual order; | |
* - to create a link, using aria-owns, between spans in the textLayer and | |
* annotations in the annotationLayer. The goal is to help to know | |
* where the annotations are in the text flow. |
src/display/accessibility.js
Outdated
if ( | ||
typeof PDFJSDev === "undefined" || | ||
PDFJSDev.test("!PRODUCTION || TESTING") | ||
) { | ||
if (DEBUG) { | ||
node.style.backgroundColor = "red"; | ||
setTimeout(() => { | ||
node.style.backgroundColor = ""; | ||
}, 2000); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having to manually edit the code, in order to enable debugging, seems less than ideal.
The elements in question are always placed in the textLayer, right?
Because if so, it'd be much better to piggyback on the existing textLayer=visible
debugging hash-parameter with appropriate rules added in the web/debugger.css
file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent idea !
src/display/display_utils.js
Outdated
if (typeof globalThis.crypto !== "undefined") { | ||
return `${globalThis.crypto.randomUUID()}-`; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the performance of this code like?
Given that we use a hard-coded prefix string with the Editing-functionality, I suppose that we could try a similar approach here as well if that'd make things simpler and more efficient. (As long as the resulting id
is unlikely to clash with named destinations.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran this on my powerful computer:
s = performance.now(); for (let i = 0; i < 1e7; i++) { crypto.randomUUID(); }; d = performance.now() - s
and I got 9475ms
so a unique call should be around 1ms
, so in considering that it's called one time I think it's acceptable.
That said, it's on my powerful computer...
I use the ids in some tests (here and in m-c (i.e. https://searchfox.org/mozilla-central/search?q=%23pdfjs_internal_editor_&path=&case=false®exp=false)).
I think we could use isInAutomation
and/or preprocessing stuff we have here to generate a specific id for test or add an attribute... I'm not sure that's a good idea...
web/pdf_page_view.js
Outdated
this._accessibilityManager = new AccessibilityManager(div); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably don't want to initialize this unconditionally, since the textLayer may not actually be used (depending on options). It ought to suffice, as far as I can tell, to initialize it a the top this block:
Line 699 in 4f6cd05
if (this.textLayerMode !== TextLayerMode.DISABLE && this.textLayerFactory) { |
web/text_layer_builder.js
Outdated
@@ -114,6 +119,7 @@ class TextLayerBuilder { | |||
this.textLayerDiv.append(textLayerFrag); | |||
this._finishRendering(); | |||
this.highlighter?.enable(); | |||
this.accessibilityManager?.onTextLayerRendered(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally speaking, let's make the AccessibilityManager
a bit more similar to the TextHighlighter
class.
Hence, let's call this method enable
instead. (You might also want to introduce a disable
method, to handle any clean-up when the textLayer goes away.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing, that could perhaps simplify things and reduce the number of DOM lookups in the AccessibilityManager
-code, would be to again follow the TextHighlighter
-class and pass in the textLayer-divs similar to:
pdf.js/web/text_layer_builder.js
Line 99 in 4f6cd05
this.highlighter?.setTextMapping(this.textDivs, this.textContentItemsStr); |
src/display/accessibility.js
Outdated
#pageDiv; | ||
|
||
/** | ||
* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: This line can be removed.
…bug 1780375) An annotation doesn't have to be in the text flow, hence it's likely a bad idea to insert its text in the text layer. But the text must be visible from a screen reader point of view so it must somewhere in the DOM. So with this patch, the text from a FreeText annotation is extracted and added in a div in its HTML counterpart, and with the patch mozilla#15237 the text should be visible and positioned relatively to the text flow.
…bug 1780375) An annotation doesn't have to be in the text flow, hence it's likely a bad idea to insert its text in the text layer. But the text must be visible from a screen reader point of view so it must somewhere in the DOM. So with this patch, the text from a FreeText annotation is extracted and added in a div in its HTML counterpart, and with the patch mozilla#15237 the text should be visible and positioned relatively to the text flow.
…bug 1780375) An annotation doesn't have to be in the text flow, hence it's likely a bad idea to insert its text in the text layer. But the text must be visible from a screen reader point of view so it must somewhere in the DOM. So with this patch, the text from a FreeText annotation is extracted and added in a div in its HTML counterpart, and with the patch mozilla#15237 the text should be visible and positioned relatively to the text flow.
…bug 1780375) An annotation doesn't have to be in the text flow, hence it's likely a bad idea to insert its text in the text layer. But the text must be visible from a screen reader point of view so it must somewhere in the DOM. So with this patch, the text from a FreeText annotation is extracted and added in a div in its HTML counterpart, and with the patch mozilla#15237 the text should be visible and positioned relatively to the text flow.
0e13a95
to
60ba211
Compare
…bug 1780375) An annotation doesn't have to be in the text flow, hence it's likely a bad idea to insert its text in the text layer. But the text must be visible from a screen reader point of view so it must somewhere in the DOM. So with this patch, the text from a FreeText annotation is extracted and added in a div in its HTML counterpart, and with the patch mozilla#15237 the text should be visible and positioned relatively to the text flow.
60ba211
to
95d2b04
Compare
95d2b04
to
38a0e2f
Compare
Thanks. I tested this with both a tagged and an untagged PDF and I can now see the text annotations. Nice! Ideally, I think the annotations would have role="insertion" or similar so you can see they're annotations (as opposed to part of the normal text). It's tricky to know what role is best here; some might argue these are more like comments than suggested insertions, in which case role="comment" is probably better. Regardless, I don't think this should block this; it's a nice-to-have and could be done in a follow-up. |
…bug 1780375) An annotation doesn't have to be in the text flow, hence it's likely a bad idea to insert its text in the text layer. But the text must be visible from a screen reader point of view so it must somewhere in the DOM. So with this patch, the text from a FreeText annotation is extracted and added in a div in its HTML counterpart, and with the patch mozilla#15237 the text should be visible and positioned relatively to the text flow.
38a0e2f
to
2d68274
Compare
@Snuffleupagus, could you have a final look on this PR ? |
src/display/display_utils.js
Outdated
const IdRandomPrefix = (() => { | ||
if (typeof globalThis.crypto !== "undefined") { | ||
return `${globalThis.crypto.randomUUID()}-`; | ||
} | ||
|
||
const digits = new Array(36) | ||
.fill(null) | ||
.map(() => Math.floor(Math.random() * 16).toString(16)); | ||
digits[8] = digits[13] = digits[18] = digits[23] = "-"; | ||
|
||
return digits.join(""); | ||
})(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To simplify things, how about we just use a fixed prefix for now?
Similar to the one used with the editor, since that ought the limit risk of accidental matches with any named destinations:
AnnotationIdPrefix = "pdfjs_internal_id_";
If this turns out to be problematical, we can always change things later on.
src/display/editor/tools.js
Outdated
@@ -53,7 +53,7 @@ class IdManager { | |||
* @returns {string} | |||
*/ | |||
getId() { | |||
return `${AnnotationEditorPrefix}${this.#id++}`; | |||
return `${AnnotationEditorPrefix}${IdRandomPrefix}${this.#id++}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not immediately obvious to me why do we need "double" prefixes here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was to be sure to have an unique id and make it findable (with a query selector) in tests.
web/base_viewer.js
Outdated
@@ -1650,6 +1653,7 @@ class BaseViewer { | |||
enhanceTextSelection = false, | |||
eventBus, | |||
highlighter, | |||
accessibilityManager, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency the method below:
accessibilityManager, | |
accessibilityManager = null, |
web/base_viewer.js
Outdated
@@ -1752,6 +1761,7 @@ class BaseViewer { | |||
uiManager = this.#annotationEditorUIManager, | |||
pageDiv, | |||
pdfPage, | |||
accessibilityManager, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency the method above:
accessibilityManager, | |
accessibilityManager = null, |
web/default_factory.js
Outdated
@@ -118,13 +124,15 @@ class DefaultAnnotationEditorLayerFactory { | |||
uiManager = null, | |||
pageDiv, | |||
pdfPage, | |||
accessibilityManager, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency, also given the JSDoc:
accessibilityManager, | |
accessibilityManager = null, |
web/default_factory.js
Outdated
@@ -176,6 +185,7 @@ class DefaultTextLayerFactory { | |||
enhanceTextSelection = false, | |||
eventBus, | |||
highlighter, | |||
accessibilityManager, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency, also given the JSDoc:
accessibilityManager, | |
accessibilityManager = null, |
web/text_accessibility.js
Outdated
get #hasTextLayer() { | ||
return !!this.#pageDiv.querySelector(":scope > .textLayer .endOfContent"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we still need this method and its DOM access, since you already know that the textLayer is available once the enable
-method has run?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some elements could have been added before the text layer finished to render, and when enable
is called those elements are really inserted.
So we need to know that the text layer is still rendering in order to push those elements in a queue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we need to know that the text layer is still rendering in order to push those elements in a queue.
But the enable
-call occurs at the point when the textLayer has finished rendering, so you already know when that happens. Perhaps what you really want here is an #enabled
-property, similar to the TextHighlighter
-class, that you check instead?
web/debugger.css
Outdated
@@ -101,3 +101,7 @@ | |||
background-color: rgba(255, 255, 255, 0.6); | |||
color: rgba(0, 0, 0, 1); | |||
} | |||
|
|||
#viewer.textLayer-visible .textLayer span[aria-owns] { | |||
background-color: red; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you perhaps want set an opacity here as well, given the background-color
definition for "normal" textLayer spans above?
Lines 88 to 89 in e1e97c6
#viewer.textLayer-visible .textLayer span { | |
background-color: rgba(255, 255, 0, 0.1); |
Also, can we please move this block to just after that definition above since they're connected?
web/text_accessibility.js
Outdated
// When zooming the text layer is removed from the DOM and sometimes | ||
// it's rebuilt hence the nodes are no longer valid. | ||
|
||
const textLayer = this.#pageDiv.getElementsByClassName("textLayer").item(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the TextHighlighter
-class, why can't you add a setTextMapping
-method in this class instead and call that one using something like the following
this.accessibilityManager?.setTextMapping(this.textDivs);
placed just after this line?
That way, the DOM elements should be directly available without the need for any additional DOM lookups here.
web/pdf_page_view.js
Outdated
@@ -697,6 +698,7 @@ class PDFPageView { | |||
|
|||
let textLayer = null; | |||
if (this.textLayerMode !== TextLayerMode.DISABLE && this.textLayerFactory) { | |||
this._accessibilityManager = new TextAccessibilityManager(div); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given how the textLayer is being re-created on zooming/rotation, but the annotationLayer and annotationEditorLayer are kept, will this work correctly as-is?
With this code the annotationLayer/annotationEditorLayer will potentially contain a reference to an "old" TextAccessibilityManager
, which seems like it probably doesn't work.
Can we just re-use the same TextAccessibilityManager
-instance, but still lazily initialized, with the following code?
this._accessibilityManager = new TextAccessibilityManager(div); | |
this._accessibilityManager ||= new TextAccessibilityManager(div); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found this bug.
2d68274
to
0c5713c
Compare
/botio test |
From: Bot.io (Linux m4)ReceivedCommand cmd_test from @calixteman received. Current queue size: 0 Live output at: http://54.241.84.105:8877/8a13b720f1d5e46/output.txt |
From: Bot.io (Windows)ReceivedCommand cmd_test from @calixteman received. Current queue size: 0 Live output at: http://54.193.163.58:8877/d51730018bbc178/output.txt |
web/annotation_layer_builder.css
Outdated
@@ -210,7 +210,7 @@ | |||
|
|||
.annotationLayer .popup { | |||
position: absolute; | |||
z-index: 200; | |||
z-index: 2000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing that just occurred to me, although I've not tested it:
Do you actually need this property here, now that an explicit z-index is assigned in the JS code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems useless: I removed it.
I changed:
https://github.com/mozilla/pdf.js/pull/15237/files#diff-d7b040092cf6be09a276b785ba03c46e79bc8342cf4ae4fb1bc139dea8513425R1906
because the +=
was just concatenating "1000" to the zindex string when the -=
below was subtracting 1000.
c3d8996
to
1b351d5
Compare
From: Bot.io (Windows)FailedFull output at http://54.193.163.58:8877/d51730018bbc178/output.txt Total script time: 25.56 mins
Image differences available at: http://54.193.163.58:8877/d51730018bbc178/reftest-analyzer.html#web=eq.log |
From: Bot.io (Linux m4)FailedFull output at http://54.241.84.105:8877/8a13b720f1d5e46/output.txt Total script time: 26.28 mins
Image differences available at: http://54.241.84.105:8877/8a13b720f1d5e46/reftest-analyzer.html#web=eq.log |
/botio test |
From: Bot.io (Linux m4)ReceivedCommand cmd_test from @calixteman received. Current queue size: 0 Live output at: http://54.241.84.105:8877/1b42d8931691167/output.txt |
From: Bot.io (Windows)ReceivedCommand cmd_test from @calixteman received. Current queue size: 0 Live output at: http://54.193.163.58:8877/91374a9669fcaf8/output.txt |
From: Bot.io (Linux m4)FailedFull output at http://54.241.84.105:8877/1b42d8931691167/output.txt Total script time: 26.32 mins
Image differences available at: http://54.241.84.105:8877/1b42d8931691167/reftest-analyzer.html#web=eq.log |
From: Bot.io (Windows)FailedFull output at http://54.193.163.58:8877/91374a9669fcaf8/output.txt Total script time: 28.88 mins
Image differences available at: http://54.193.163.58:8877/91374a9669fcaf8/reftest-analyzer.html#web=eq.log |
The "regressions" are a matter of z-index when several popups are displayed. |
Unless my memory is completely off, isn't part of the issue (or possibly all of it) caused by the fact that serializing the HTML content isn't able to take the
Have you tested the affected documents in the viewer, to make sure that these "regressions" are indeed ref-test only and that nothing is actually functionally broken in the viewer? |
} | ||
|
||
this.#enabled = true; | ||
this.#textChildren.sort(TextAccessibilityManager.#compareElementPositions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, this is in-place sort right?
Given how objects are passed by reference in JS, this object is the same as e.g. the textDivs
property used in the TextHighlighter
-class. Hence, can this re-ordering possibly affect highlighting of search-results?
In any case, to prevent future bugs, you might want to create a copy rather than modifying in place here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.
A way to fix those issues, would be to set the dimension to |
…ions (bug 1780375) This patch doesn't structurally change the text layer: it just adds some aria-owns attributes to some spans. The aria-owns attribute expect to have an element id, hence it's why it adds back an id on the element rendering an annotation, but this id is built in using crypto.randomUUID to avoid any potential issues with the hash in the url. The elements in the annotation layer are moved into the DOM in order to have them in the same "order" as they visually are. The overall goal is to help screen readers to present to the user the annotations as they visually are and as they come in the text flow. It is clearly not perfect, but it should improve readability for some people with visual disabilities.
1b351d5
to
f316300
Compare
I'd be a bit surprised if there's not other fallout from such a change, so probably not somewhat that we want to attempt here. Let's land this as-is, since hopefully most issues should've been found now :-) |
/botio makeref |
From: Bot.io (Linux m4)ReceivedCommand cmd_makeref from @calixteman received. Current queue size: 0 Live output at: http://54.241.84.105:8877/8d5ed16ff3494f6/output.txt |
From: Bot.io (Windows)ReceivedCommand cmd_makeref from @calixteman received. Current queue size: 1 Live output at: http://54.193.163.58:8877/abe0263d2f91bc8/output.txt |
From: Bot.io (Linux m4)SuccessFull output at http://54.241.84.105:8877/8d5ed16ff3494f6/output.txt Total script time: 22.85 mins
|
From: Bot.io (Windows)SuccessFull output at http://54.193.163.58:8877/abe0263d2f91bc8/output.txt Total script time: 22.60 mins
|
This patch doesn't structurally change the text layer: it just adds some aria-owns
attributes to some spans.
The aria-owns attribute expect to have an element id, hence it's why it adds back an
id on the element rendering an annotation, but this id is built in using crypto.randomUUID
to avoid any potential issues with the hash in the url.
The elements in the annotation layer are moved into the DOM in order to have them in the
same "order" as they visually are.
The overall goal is to help screen readers to present to the user the annotations as
they visually are and as they come in the text flow.
It is clearly not perfect, but it should improve readability for some people with visual
disabilities.