Keeps one of MAIDR's fields -- the braille textarea or the review input --
readable on whatever page it is drawn in.
A field left at 4.5:1 or more is left alone, so a page that styles its
fields keeps its own look. Below that, the field takes both colours, as a
pair, inline and !important so that no rule of the page's outweighs
them: those of the article around it, which is the text the page itself
shows around the chart, or the browser's own field colours where that
text is unreadable too. While high contrast mode is painted, the pair is
always the reader's own, set only where a page's !important colour
keeps the field from showing it, and never measured (see pairFor).
Measured, not cascaded, because no rule of a fixed specificity can be sure
of both colours: a page that sets one of them at the same specificity or
more, or in a reset that inherits one and clears the other, splits any
pair a rule hands the field. Under forced colours, which replace both
colours whatever is set, the floor stays out.
A transition on the field's colours is finished before it is measured, and
again after the pair is set (see settleColourTransitions).
Each check first reads what it can without touching the page (see
inputsOf), and measures only when that has changed: taking the pair off
to measure the field's own colours, and setting it again, is a change to
the page that a page's own MutationObserver sees, and a page that answers
such a change by writing to its root or body would otherwise be answered
in turn, for ever. So a change to the field's own colours alone, with the
pair in place, waits for the colours around it to change.
Checked at once whenever its caller asks (see useReadableField, which
asks on each of the reader's steps and whenever high contrast mode or its
colours change), and on its own whenever the field's colours can change
without the reader doing anything, which review, taking no steps while it
is open, would otherwise never catch:
at once, when the field gains or loses focus, so a page's :focus rule
is measured (braille is measured before it takes focus);
on the next frame, when the page's root or body changes an attribute's
value, which is how a theme toggle switches theme (a class, a
data-theme, a style); a write of the value already there is no change;
on the next frame, when the system's colour scheme changes, which a
page's prefers-color-scheme rules follow;
on the next frame, when a stylesheet or a <style> finishes loading,
which is when a theme switch that enables a stylesheet takes effect:
Quarto's switches the dark sheet's rel and then the body's class, and
the sheet applies once it has loaded, after the class change has been
checked (Chromium fires load then, Firefox error, so both count).
Every one of these is followed by a check on each frame after it, until
five frames in a row find nothing changed and no animation is moving, or
waiting out its delay, on the field or any of its ancestors, or until
MAX_FRAMES frames (two seconds at 60 Hz, one at 120 Hz) have passed since
the last of them, so a transition longer than that is left where it is (see
framesOf). A page that reports a change every frame, writing to its root
on each, is checked once every four frames instead. A check on a frame
reads the colours among the frame's animation callbacks, before its style
recalculation: the read brings that recalculation forward rather than
adding one, unless the page changes its styles again later in the same
callbacks.
Nothing else is watched: a class on an element between the body and the
chart, a rule inserted into a stylesheet already there, or a :hover or
:focus-within rule is seen at the next check anything above makes, the
reader's next step at the latest for braille, and then only where it
changed something a check reads (see inputsOf).
A check the floor makes on its own, on focus or on a frame, has no caller
to hand an error to: it logs what it throws and leaves the field as it is,
and one on a frame ends the frames that would follow it.
Keeps one of MAIDR's fields -- the braille textarea or the review input -- readable on whatever page it is drawn in.
A field left at 4.5:1 or more is left alone, so a page that styles its fields keeps its own look. Below that, the field takes both colours, as a pair, inline and
!importantso that no rule of the page's outweighs them: those of the article around it, which is the text the page itself shows around the chart, or the browser's own field colours where that text is unreadable too. While high contrast mode is painted, the pair is always the reader's own, set only where a page's!importantcolour keeps the field from showing it, and never measured (seepairFor).Measured, not cascaded, because no rule of a fixed specificity can be sure of both colours: a page that sets one of them at the same specificity or more, or in a reset that inherits one and clears the other, splits any pair a rule hands the field. Under forced colours, which replace both colours whatever is set, the floor stays out. A transition on the field's colours is finished before it is measured, and again after the pair is set (see
settleColourTransitions).Each check first reads what it can without touching the page (see
inputsOf), and measures only when that has changed: taking the pair off to measure the field's own colours, and setting it again, is a change to the page that a page's own MutationObserver sees, and a page that answers such a change by writing to its root or body would otherwise be answered in turn, for ever. So a change to the field's own colours alone, with the pair in place, waits for the colours around it to change.Checked at once whenever its caller asks (see
useReadableField, which asks on each of the reader's steps and whenever high contrast mode or its colours change), and on its own whenever the field's colours can change without the reader doing anything, which review, taking no steps while it is open, would otherwise never catch::focusrule is measured (braille is measured before it takes focus);data-theme, a style); a write of the value already there is no change;prefers-color-schemerules follow;<style>finishes loading, which is when a theme switch that enables a stylesheet takes effect: Quarto's switches the dark sheet'sreland then the body's class, and the sheet applies once it has loaded, after the class change has been checked (Chromium firesloadthen, Firefoxerror, so both count).Every one of these is followed by a check on each frame after it, until five frames in a row find nothing changed and no animation is moving, or waiting out its delay, on the field or any of its ancestors, or until
MAX_FRAMESframes (two seconds at 60 Hz, one at 120 Hz) have passed since the last of them, so a transition longer than that is left where it is (seeframesOf). A page that reports a change every frame, writing to its root on each, is checked once every four frames instead. A check on a frame reads the colours among the frame's animation callbacks, before its style recalculation: the read brings that recalculation forward rather than adding one, unless the page changes its styles again later in the same callbacks.Nothing else is watched: a class on an element between the body and the chart, a rule inserted into a stylesheet already there, or a
:hoveror:focus-withinrule is seen at the next check anything above makes, the reader's next step at the latest for braille, and then only where it changed something a check reads (seeinputsOf).A check the floor makes on its own, on focus or on a frame, has no caller to hand an error to: it logs what it throws and leaves the field as it is, and one on a frame ends the frames that would follow it.