Skip to content

Move a11y attribute and property strings to be taken from shared objects - #1551

Open
dpvc wants to merge 2 commits into
feature/common-structurefrom
refactor/a11y-strings
Open

Move a11y attribute and property strings to be taken from shared objects#1551
dpvc wants to merge 2 commits into
feature/common-structurefrom
refactor/a11y-strings

Conversation

@dpvc

@dpvc dpvc commented Aug 13, 2026

Copy link
Copy Markdown
Member

This PR moves the strings used for the various data-* attributes in the a11y components into objects, similar to the SemAttr array used in the speech processing. This both shortens the references, and guarantees that they are the same. It also makes it possible to change them easier, if that is desired, as changes only need to be made in one place.

We also fix three other issues that were found while making the string changes:

  1. THe shared __locales__ files weren't being includes in the MathJax._ object for some of the components, so their config.json files were modified to do that explicitly.
  2. There was a collapsedComplecity property being checked that is never set anywhere in the code base. I believe that it was left over from an earlier usage and that this should have been changed to collapse-complexity, so I've change it to that.
  3. The semantic info regions would move lower and lower on the page as you move over different items in the expression when more than one was being displayed at a time. This is probably due to something I changed in the feature/common-structure branch somewhere (perhaps in how the regions start/stop or update), but I didn't track it down specifically. Instead, an easy fix is to stop the loop that places the regions when you get to the current region. I also simplified the loops.

This touches a lot of files, but most of the changes are just substituting the object references for the literal strings. Some spacing in comments is also adjusted for alignment.


Details

The component config files are modoified to load load the files that define the strings, and to load __locales__ when that isn't already being done (so their Component.ts files will be available to be shared). Because the semantic-enrich component is shared by all the a11y components, the strings that are shared by more than one components are included in the a11y/semantic-enrich component, so that the stings aren't duplicated in each component. Strings that are used in only one component are included only in that one component. (This is true for the complexity and explorer components).

Some strings, like the maction strings used for marking the mactions from the complexity component, are used in components that aren't based on the semantic enrich component, and so they will include those strings themselves. This includes the ui/menu component, and the two output components, since the maction support needs to use the maction strings, and the common scriptbase wrapper needs two semantic attributes.

This does mean there is a small amount of duplication due to those strings needing to be used in several unrelated components, but the cost is small, and while the duplication appears in the files, it will not take up more memory as the strings will be stored in the same place, so a later component overwrites the original strings with the second copy of the same strings.

There are two alternaitve approaches that could be use to avoid any duplication, however. The first would be to move the strings to the core component, so they are available to be shared with all other components. The disadvantage is that this means strings that if the strings will be loaded even if the a11y components are not. That would not affect those who use a combined configuration (like tex-chtml.js), but would affect those who load components individually and don't include any a11y components.

The second approach would be to use export const enum objects rather than export const objects. That would cause Typescript to inline the strings rather than include object references. That means there are no objects to be shared as the strings are inserted into the files directly at compile time. This would make the files be essentially the same as they are now (with explicit strings everywhere), so nothing needs to be shared. The downside here is that the strings are no longer available in MathJax._ for other code to reference, so run-time patches would need to use the explicit strings. Also, the strings themselves are often longer than the object references, which mens we don't get any file-size savings that we do by using the common objects. (E.g., 'data-semantic-id' is longer than SEM.ID, and we save 12 characters in the file that needs to be downloaded to the browser for every reference to this string. Not a huge savings, but still, any savings in file size is useful.

In the components/mjs/a11y/complexity/config.json file, semantic-enrich.js was being incorrectly included, so has been removed. The complexity component has the semantic-enrich component as a dependency, so we don't want to include it directly.

The explorer component wasn't loading the a11y/__locales__ into the mathjax._ object, so that has been included here.

The semantic-enrich configuration now loads the common strings (and its _locales__ via the semantic-enrich subdirectory).

The adaptors/linkedom needs to have its __locales__ included (not really related to the string changes, but I found it when the __locales__ for the a11y components weren't being loaded, so include it here as well). The same for the input/mml and input/tex components.

As mentioned above, the output components need the semantic-enrich and maction strings for the scriptbase and maction wrappers. They aren't shared, since these components don't have semantic-enrich as a dependency, so mush be included explicitly so that they appear in the MathJax._ object are aren't duplicated when both components are loaded.

Similarly, the ui/menu component needs some of the attribute strings, and it also was not merging the __locales__ values into the shared MathJax._ object, so they are included here.


The changes in a11y/complexity/collapse.ts are just the replacement of the strings with the object references. The strings themselves are in a11y/complexity/strings.ts. Note that data-semantic-complexity is changed to data-collapse-complexity, as it is not an SRE attribute. This is a potential breaking change, but I doubt anyone is using these values. If they are, they can change the attribute back using the MathJax.loader['a11y/complexity'].ready() function, as long as we use actual objects, not cont enum, for these strings.

The changes to visitor.ts are just the string substations and some alignment adjustments in the comments.

For explorer.ts, we change the strings, and also use a new SAVED_HREF string from KeyExplorer.ts for the attribute that stored the saves href attributes during exploration.

The ATTR array already in use in Highlighter.ts is renames HILITE to make it more clear where it comes from, and is now stored in a separate strings.ts file for the explorer. The Explorer.ts file is modified to use the new array name and location.

The ExplorerPool.ts file has its semantic strings exchanged for the SEM object.

In KeyExplorer.ts, most changes are just the string replacements. A new SAVED_HREF constant is used for the attribute used to save the original href attributes. (I suppose this could have been in the explorer/strings.ts file, perhaps as HREF.SAVED; I can do that if you want that for consistency). The change in firstNode() is to eliminate the need for a redundant return node..querySelector(nav) call.

The MouseExplorer.ts just has strings replaced by the object references.

In Region.ts, we defined a set of attributes that are used internally for marking the magnification regions as clones (so that CSS can target the magnification and not the original expression). We also adjust the stackRegions() method, as mentioned above, so that we stop stacking when we get to the current region rather than including all the regions below it in its position. I'm not sure why this worked in the past, but suspect that the regions were removed and re-added, so that there were not any below it. In any case, this now works, and the loop can be simplified to use for-of rather than an index. The other changes are just replacing the strings with the object references.

The TreeExplorer.ts changes are just the string replacements.

The explorer/strings.ts file just defines the HILITE strings (the old ATTR list, plus a PREFIX.

The changes in semantic-enrich.ts are just the replacement of strings with object references.

The semantic-enrich/maction.ts file defines the strings for maction attributes used for collapsing sub expressions. The names now use data-maction- rather than data-collapse- for the group and group id attributes. These are not breaking changes, since those attributes were introduced in feature/common-structure, which hasn't been merged yet.

The semantic-enrich/strings.ts file defines the data-semantic- strings used in the a11y components and elsewhere. Note that there is already a SemAttr array in SpeechUtil.ts that holds some data-semantic- attributes, and it would be possible to combine these arrays. They are used in the GeneratorPool, WebWorker, and KeyExplorer files, so could be added to the new SEM array easily.

There remaining files are just strings replacements with objects references, and the speech/strings.ts definition file.

@dpvc
dpvc requested a review from zorkow August 13, 2026 12:14
@dpvc dpvc added this to the v4.2 milestone Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant