[Editor] Add a tooltip showing the alt text when hovering the alt-text button (bug 1844952)
This commit is contained in:
parent
8d326e5e30
commit
7952a36384
@ -265,9 +265,9 @@ editor_ink2_aria_label=Draw Editor
|
|||||||
editor_ink_canvas_aria_label=User-created image
|
editor_ink_canvas_aria_label=User-created image
|
||||||
|
|
||||||
# Alt-text dialog
|
# Alt-text dialog
|
||||||
# LOCALIZATION NOTE (alt_text_button_label): Alternative text (alt text) helps
|
# LOCALIZATION NOTE (editor_alt_text_button_label): Alternative text (alt text) helps
|
||||||
# when people can't see the image.
|
# when people can't see the image.
|
||||||
alt_text_button_label=Alt text
|
editor_alt_text_button_label=Alt text
|
||||||
editor_alt_text_dialog_label=Choose an option
|
editor_alt_text_dialog_label=Choose an option
|
||||||
editor_alt_text_dialog_description=Alt text (alternative text) helps when people can’t see the image or when it doesn’t load.
|
editor_alt_text_dialog_description=Alt text (alternative text) helps when people can’t see the image or when it doesn’t load.
|
||||||
editor_alt_text_enter_description_label=Enter a description
|
editor_alt_text_enter_description_label=Enter a description
|
||||||
@ -276,3 +276,4 @@ editor_alt_text_mark_decorative_label=Mark as decorative
|
|||||||
editor_alt_text_mark_decorative_description=This is best for images that aren’t informative, like borders or stylistic elements.
|
editor_alt_text_mark_decorative_description=This is best for images that aren’t informative, like borders or stylistic elements.
|
||||||
editor_alt_text_cancel_button=Cancel
|
editor_alt_text_cancel_button=Cancel
|
||||||
editor_alt_text_save_button=Save
|
editor_alt_text_save_button=Save
|
||||||
|
editor_alt_text_decorative_tooltip=Marked as decorative
|
||||||
|
@ -40,7 +40,9 @@ class AnnotationEditor {
|
|||||||
|
|
||||||
#altTextButton = null;
|
#altTextButton = null;
|
||||||
|
|
||||||
#altTextAriaDescription = null;
|
#altTextTooltip = null;
|
||||||
|
|
||||||
|
#altTextTooltipTimeout = null;
|
||||||
|
|
||||||
#keepAspectRatio = false;
|
#keepAspectRatio = false;
|
||||||
|
|
||||||
@ -142,7 +144,10 @@ class AnnotationEditor {
|
|||||||
*/
|
*/
|
||||||
static initialize(l10n, options = null) {
|
static initialize(l10n, options = null) {
|
||||||
AnnotationEditor._l10nPromise ||= new Map(
|
AnnotationEditor._l10nPromise ||= new Map(
|
||||||
["alt_text_button_label"].map(str => [str, l10n.get(str)])
|
[
|
||||||
|
"editor_alt_text_button_label",
|
||||||
|
"editor_alt_text_decorative_tooltip",
|
||||||
|
].map(str => [str, l10n.get(str)])
|
||||||
);
|
);
|
||||||
if (options?.strings) {
|
if (options?.strings) {
|
||||||
for (const str of options.strings) {
|
for (const str of options.strings) {
|
||||||
@ -818,9 +823,11 @@ class AnnotationEditor {
|
|||||||
}
|
}
|
||||||
const altText = (this.#altTextButton = document.createElement("button"));
|
const altText = (this.#altTextButton = document.createElement("button"));
|
||||||
altText.className = "altText";
|
altText.className = "altText";
|
||||||
AnnotationEditor._l10nPromise.get("alt_text_button_label").then(msg => {
|
AnnotationEditor._l10nPromise
|
||||||
altText.textContent = msg;
|
.get("editor_alt_text_button_label")
|
||||||
});
|
.then(msg => {
|
||||||
|
altText.textContent = msg;
|
||||||
|
});
|
||||||
altText.tabIndex = "0";
|
altText.tabIndex = "0";
|
||||||
altText.addEventListener(
|
altText.addEventListener(
|
||||||
"click",
|
"click",
|
||||||
@ -836,6 +843,18 @@ class AnnotationEditor {
|
|||||||
this._uiManager.editAltText(this);
|
this._uiManager.editAltText(this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const DELAY_TO_SHOW_TOOLTIP = 500;
|
||||||
|
altText.addEventListener("mouseenter", () => {
|
||||||
|
this.#altTextTooltipTimeout = setTimeout(() => {
|
||||||
|
this.#altTextTooltipTimeout = null;
|
||||||
|
this.#altTextTooltip?.classList.add("show");
|
||||||
|
}, DELAY_TO_SHOW_TOOLTIP);
|
||||||
|
});
|
||||||
|
altText.addEventListener("mouseleave", () => {
|
||||||
|
clearTimeout(this.#altTextTooltipTimeout);
|
||||||
|
this.#altTextTooltipTimeout = null;
|
||||||
|
this.#altTextTooltip?.classList.remove("show");
|
||||||
|
});
|
||||||
this.#setAltTextButtonState();
|
this.#setAltTextButtonState();
|
||||||
this.div.append(altText);
|
this.div.append(altText);
|
||||||
if (!AnnotationEditor.SMALL_EDITOR_SIZE) {
|
if (!AnnotationEditor.SMALL_EDITOR_SIZE) {
|
||||||
@ -849,36 +868,30 @@ class AnnotationEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#setAltTextButtonState() {
|
async #setAltTextButtonState() {
|
||||||
const button = this.#altTextButton;
|
const button = this.#altTextButton;
|
||||||
if (!button) {
|
if (!button || (!this.#altTextDecorative && !this.#altText)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: remove the aria-describedby once the tooltip stuff is implemented:
|
let tooltip = this.#altTextTooltip;
|
||||||
// the tooltip willl contain a span with the description, hence we could use
|
if (!tooltip) {
|
||||||
// it.
|
this.#altTextTooltip = tooltip = document.createElement("span");
|
||||||
if (this.#altTextDecorative) {
|
tooltip.className = "tooltip";
|
||||||
button.classList.add("done");
|
tooltip.setAttribute("role", "tooltip");
|
||||||
button.title = "";
|
const id = (tooltip.id = `alt-text-tooltip-${this.id}`);
|
||||||
if (this.#altTextAriaDescription) {
|
button.append(tooltip);
|
||||||
button.removeAttribute("aria-describedby");
|
button.setAttribute("aria-describedby", id);
|
||||||
this.#altTextAriaDescription.remove();
|
|
||||||
this.#altTextAriaDescription = null;
|
|
||||||
}
|
|
||||||
} else if (this.#altText) {
|
|
||||||
button.classList.add("done");
|
|
||||||
button.title = this.#altText;
|
|
||||||
let description = this.#altTextAriaDescription;
|
|
||||||
if (!description) {
|
|
||||||
this.#altTextAriaDescription = description =
|
|
||||||
document.createElement("span");
|
|
||||||
description.className = "description";
|
|
||||||
const id = (description.id = `${this.id}-alt-text`);
|
|
||||||
button.append(description);
|
|
||||||
button.setAttribute("aria-describedby", id);
|
|
||||||
}
|
|
||||||
description.innerText = this.#altText;
|
|
||||||
}
|
}
|
||||||
|
button.classList.add("done");
|
||||||
|
if (this.#altTextDecorative) {
|
||||||
|
tooltip.innerText = await AnnotationEditor._l10nPromise.get(
|
||||||
|
"editor_alt_text_decorative_tooltip"
|
||||||
|
);
|
||||||
|
tooltip.classList.add("decorative");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tooltip.innerText = this.#altText;
|
||||||
|
tooltip.classList.remove("decorative");
|
||||||
}
|
}
|
||||||
|
|
||||||
getClientDimensions() {
|
getClientDimensions() {
|
||||||
|
@ -529,13 +529,53 @@
|
|||||||
mask-image: var(--alt-text-done-image);
|
mask-image: var(--alt-text-done-image);
|
||||||
}
|
}
|
||||||
|
|
||||||
& .description {
|
& .tooltip {
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
|
||||||
height: 0;
|
&.decorative {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.show {
|
||||||
|
--alt-text-tooltip-bg: #f0f0f4;
|
||||||
|
--alt-text-tooltip-fg: #15141a;
|
||||||
|
--alt-text-tooltip-border: #8f8f9d;
|
||||||
|
--alt-text-tooltip-shadow: 0px 2px 6px 0px rgba(58, 57, 68, 0.2);
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
--alt-text-tooltip-bg: #1c1b22;
|
||||||
|
--alt-text-tooltip-fg: #fbfbfe;
|
||||||
|
--alt-text-tooltip-shadow: 0px 2px 6px 0px #15141a;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (forced-colors: active) {
|
||||||
|
--alt-text-tooltip-bg: Canvas;
|
||||||
|
--alt-text-tooltip-fg: CanvasText;
|
||||||
|
--alt-text-tooltip-border: CanvasText;
|
||||||
|
--alt-text-tooltip-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 2px);
|
||||||
|
inset-inline-start: 0;
|
||||||
|
padding-block: 2px 3px;
|
||||||
|
padding-inline: 3px;
|
||||||
|
max-width: 300px;
|
||||||
|
width: max-content;
|
||||||
|
height: auto;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
border: 0.5px solid var(--alt-text-tooltip-border);
|
||||||
|
background: var(--alt-text-tooltip-bg);
|
||||||
|
box-shadow: var(--alt-text-tooltip-shadow);
|
||||||
|
color: var(--alt-text-tooltip-fg);
|
||||||
|
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,8 @@ const DEFAULT_L10N_STRINGS = {
|
|||||||
editor_free_text2_aria_label: "Text Editor",
|
editor_free_text2_aria_label: "Text Editor",
|
||||||
editor_ink2_aria_label: "Draw Editor",
|
editor_ink2_aria_label: "Draw Editor",
|
||||||
editor_ink_canvas_aria_label: "User-created image",
|
editor_ink_canvas_aria_label: "User-created image",
|
||||||
alt_text_button_label: "Alt text",
|
editor_alt_text_button_label: "Alt text",
|
||||||
|
editor_alt_text_decorative_tooltip: "Marked as decorative",
|
||||||
};
|
};
|
||||||
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
|
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
|
||||||
DEFAULT_L10N_STRINGS.print_progress_percent = "{{progress}}%";
|
DEFAULT_L10N_STRINGS.print_progress_percent = "{{progress}}%";
|
||||||
|
Loading…
Reference in New Issue
Block a user