[Editor] Move the alt text button in the editor toolbar
This commit is contained in:
parent
8e2507e0e8
commit
59112a7730
@ -323,8 +323,17 @@ pdfjs-editor-ink-button-label = Draw
|
|||||||
pdfjs-editor-stamp-button =
|
pdfjs-editor-stamp-button =
|
||||||
.title = Add or edit images
|
.title = Add or edit images
|
||||||
pdfjs-editor-stamp-button-label = Add or edit images
|
pdfjs-editor-stamp-button-label = Add or edit images
|
||||||
pdfjs-editor-remove-button =
|
|
||||||
.title = Remove
|
## Remove button for the various kind of editor.
|
||||||
|
|
||||||
|
pdfjs-editor-remove-ink-button =
|
||||||
|
.title = Remove drawing
|
||||||
|
pdfjs-editor-remove-freetext-button =
|
||||||
|
.title = Remove text
|
||||||
|
pdfjs-editor-remove-stamp-button =
|
||||||
|
.title = Remove image
|
||||||
|
|
||||||
|
##
|
||||||
|
|
||||||
# Editor Parameters
|
# Editor Parameters
|
||||||
pdfjs-editor-free-text-color-input = Color
|
pdfjs-editor-free-text-color-input = Color
|
||||||
|
180
src/display/editor/alt_text.js
Normal file
180
src/display/editor/alt_text.js
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/* Copyright 2023 Mozilla Foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { noContextMenu } from "../display_utils.js";
|
||||||
|
|
||||||
|
class AltText {
|
||||||
|
#altText = "";
|
||||||
|
|
||||||
|
#altTextDecorative = false;
|
||||||
|
|
||||||
|
#altTextButton = null;
|
||||||
|
|
||||||
|
#altTextTooltip = null;
|
||||||
|
|
||||||
|
#altTextTooltipTimeout = null;
|
||||||
|
|
||||||
|
#altTextWasFromKeyBoard = false;
|
||||||
|
|
||||||
|
#editor = null;
|
||||||
|
|
||||||
|
static _l10nPromise = null;
|
||||||
|
|
||||||
|
constructor(editor) {
|
||||||
|
this.#editor = editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
static initialize(l10nPromise) {
|
||||||
|
AltText._l10nPromise ||= l10nPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
async render() {
|
||||||
|
const altText = (this.#altTextButton = document.createElement("button"));
|
||||||
|
altText.className = "altText";
|
||||||
|
const msg = await AltText._l10nPromise.get(
|
||||||
|
"pdfjs-editor-alt-text-button-label"
|
||||||
|
);
|
||||||
|
altText.textContent = msg;
|
||||||
|
altText.setAttribute("aria-label", msg);
|
||||||
|
altText.tabIndex = "0";
|
||||||
|
altText.addEventListener("contextmenu", noContextMenu);
|
||||||
|
altText.addEventListener("pointerdown", event => event.stopPropagation());
|
||||||
|
|
||||||
|
const onClick = event => {
|
||||||
|
event.preventDefault();
|
||||||
|
this.#editor._uiManager.editAltText(this.#editor);
|
||||||
|
};
|
||||||
|
altText.addEventListener("click", onClick, { capture: true });
|
||||||
|
altText.addEventListener("keydown", event => {
|
||||||
|
if (event.target === altText && event.key === "Enter") {
|
||||||
|
this.#altTextWasFromKeyBoard = true;
|
||||||
|
onClick(event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await this.#setState();
|
||||||
|
|
||||||
|
return altText;
|
||||||
|
}
|
||||||
|
|
||||||
|
finish() {
|
||||||
|
if (!this.#altTextButton) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.#altTextButton.focus({ focusVisible: this.#altTextWasFromKeyBoard });
|
||||||
|
this.#altTextWasFromKeyBoard = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get data() {
|
||||||
|
return {
|
||||||
|
altText: this.#altText,
|
||||||
|
decorative: this.#altTextDecorative,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the alt text data.
|
||||||
|
*/
|
||||||
|
set data({ altText, decorative }) {
|
||||||
|
if (this.#altText === altText && this.#altTextDecorative === decorative) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.#altText = altText;
|
||||||
|
this.#altTextDecorative = decorative;
|
||||||
|
this.#setState();
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle(enabled = false) {
|
||||||
|
if (!this.#altTextButton) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!enabled && this.#altTextTooltipTimeout) {
|
||||||
|
clearTimeout(this.#altTextTooltipTimeout);
|
||||||
|
this.#altTextTooltipTimeout = null;
|
||||||
|
}
|
||||||
|
this.#altTextButton.disabled = !enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.#altTextButton?.remove();
|
||||||
|
this.#altTextButton = null;
|
||||||
|
this.#altTextTooltip = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async #setState() {
|
||||||
|
const button = this.#altTextButton;
|
||||||
|
if (!button) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.#altText && !this.#altTextDecorative) {
|
||||||
|
button.classList.remove("done");
|
||||||
|
this.#altTextTooltip?.remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
button.classList.add("done");
|
||||||
|
|
||||||
|
AltText._l10nPromise
|
||||||
|
.get("pdfjs-editor-alt-text-edit-button-label")
|
||||||
|
.then(msg => {
|
||||||
|
button.setAttribute("aria-label", msg);
|
||||||
|
});
|
||||||
|
let tooltip = this.#altTextTooltip;
|
||||||
|
if (!tooltip) {
|
||||||
|
this.#altTextTooltip = tooltip = document.createElement("span");
|
||||||
|
tooltip.className = "tooltip";
|
||||||
|
tooltip.setAttribute("role", "tooltip");
|
||||||
|
const id = (tooltip.id = `alt-text-tooltip-${this.#editor.id}`);
|
||||||
|
button.setAttribute("aria-describedby", id);
|
||||||
|
|
||||||
|
const DELAY_TO_SHOW_TOOLTIP = 100;
|
||||||
|
button.addEventListener("mouseenter", () => {
|
||||||
|
this.#altTextTooltipTimeout = setTimeout(() => {
|
||||||
|
this.#altTextTooltipTimeout = null;
|
||||||
|
this.#altTextTooltip.classList.add("show");
|
||||||
|
this.#editor._uiManager._eventBus.dispatch("reporttelemetry", {
|
||||||
|
source: this,
|
||||||
|
details: {
|
||||||
|
type: "editing",
|
||||||
|
subtype: this.editorType,
|
||||||
|
data: {
|
||||||
|
action: "alt_text_tooltip",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}, DELAY_TO_SHOW_TOOLTIP);
|
||||||
|
});
|
||||||
|
button.addEventListener("mouseleave", () => {
|
||||||
|
if (this.#altTextTooltipTimeout) {
|
||||||
|
clearTimeout(this.#altTextTooltipTimeout);
|
||||||
|
this.#altTextTooltipTimeout = null;
|
||||||
|
}
|
||||||
|
this.#altTextTooltip?.classList.remove("show");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
tooltip.innerText = this.#altTextDecorative
|
||||||
|
? await AltText._l10nPromise.get(
|
||||||
|
"pdfjs-editor-alt-text-decorative-tooltip"
|
||||||
|
)
|
||||||
|
: this.#altText;
|
||||||
|
|
||||||
|
if (!tooltip.parentNode) {
|
||||||
|
button.append(tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
const element = this.#editor.getImageForAltText();
|
||||||
|
element?.setAttribute("aria-describedby", tooltip.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { AltText };
|
@ -23,6 +23,7 @@ import {
|
|||||||
KeyboardManager,
|
KeyboardManager,
|
||||||
} from "./tools.js";
|
} from "./tools.js";
|
||||||
import { FeatureTest, shadow, unreachable } from "../../shared/util.js";
|
import { FeatureTest, shadow, unreachable } from "../../shared/util.js";
|
||||||
|
import { AltText } from "./alt_text.js";
|
||||||
import { EditorToolbar } from "./toolbar.js";
|
import { EditorToolbar } from "./toolbar.js";
|
||||||
import { noContextMenu } from "../display_utils.js";
|
import { noContextMenu } from "../display_utils.js";
|
||||||
|
|
||||||
@ -41,17 +42,7 @@ import { noContextMenu } from "../display_utils.js";
|
|||||||
class AnnotationEditor {
|
class AnnotationEditor {
|
||||||
#allResizerDivs = null;
|
#allResizerDivs = null;
|
||||||
|
|
||||||
#altText = "";
|
#altText = null;
|
||||||
|
|
||||||
#altTextDecorative = false;
|
|
||||||
|
|
||||||
#altTextButton = null;
|
|
||||||
|
|
||||||
#altTextTooltip = null;
|
|
||||||
|
|
||||||
#altTextTooltipTimeout = null;
|
|
||||||
|
|
||||||
#altTextWasFromKeyBoard = false;
|
|
||||||
|
|
||||||
#keepAspectRatio = false;
|
#keepAspectRatio = false;
|
||||||
|
|
||||||
@ -95,10 +86,6 @@ class AnnotationEditor {
|
|||||||
|
|
||||||
static _zIndex = 1;
|
static _zIndex = 1;
|
||||||
|
|
||||||
// When one of the dimensions of an editor is smaller than this value, the
|
|
||||||
// button to edit the alt text is visually moved outside of the editor.
|
|
||||||
static SMALL_EDITOR_SIZE = 0;
|
|
||||||
|
|
||||||
static get _resizerKeyboardManager() {
|
static get _resizerKeyboardManager() {
|
||||||
const resize = AnnotationEditor.prototype._resizeWithKeyboard;
|
const resize = AnnotationEditor.prototype._resizeWithKeyboard;
|
||||||
const small = AnnotationEditorUIManager.TRANSLATE_SMALL;
|
const small = AnnotationEditorUIManager.TRANSLATE_SMALL;
|
||||||
@ -631,11 +618,6 @@ class AnnotationEditor {
|
|||||||
if (!this.#keepAspectRatio) {
|
if (!this.#keepAspectRatio) {
|
||||||
this.div.style.height = `${((100 * height) / parentHeight).toFixed(2)}%`;
|
this.div.style.height = `${((100 * height) / parentHeight).toFixed(2)}%`;
|
||||||
}
|
}
|
||||||
this.#altTextButton?.classList.toggle(
|
|
||||||
"small",
|
|
||||||
width < AnnotationEditor.SMALL_EDITOR_SIZE ||
|
|
||||||
height < AnnotationEditor.SMALL_EDITOR_SIZE
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fixDims() {
|
fixDims() {
|
||||||
@ -709,7 +691,7 @@ class AnnotationEditor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#toggleAltTextButton(false);
|
this.#altText?.toggle(false);
|
||||||
|
|
||||||
const boundResizerPointermove = this.#resizerPointermove.bind(this, name);
|
const boundResizerPointermove = this.#resizerPointermove.bind(this, name);
|
||||||
const savedDraggable = this._isDraggable;
|
const savedDraggable = this._isDraggable;
|
||||||
@ -732,7 +714,7 @@ class AnnotationEditor {
|
|||||||
|
|
||||||
const pointerUpCallback = () => {
|
const pointerUpCallback = () => {
|
||||||
this.parent.togglePointerEvents(true);
|
this.parent.togglePointerEvents(true);
|
||||||
this.#toggleAltTextButton(true);
|
this.#altText?.toggle(true);
|
||||||
this._isDraggable = savedDraggable;
|
this._isDraggable = savedDraggable;
|
||||||
window.removeEventListener("pointerup", pointerUpCallback);
|
window.removeEventListener("pointerup", pointerUpCallback);
|
||||||
window.removeEventListener("blur", pointerUpCallback);
|
window.removeEventListener("blur", pointerUpCallback);
|
||||||
@ -917,136 +899,19 @@ class AnnotationEditor {
|
|||||||
this.fixAndSetPosition();
|
this.fixAndSetPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
async addAltTextButton() {
|
|
||||||
if (this.#altTextButton) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const altText = (this.#altTextButton = document.createElement("button"));
|
|
||||||
altText.className = "altText";
|
|
||||||
const msg = await AnnotationEditor._l10nPromise.get(
|
|
||||||
"pdfjs-editor-alt-text-button-label"
|
|
||||||
);
|
|
||||||
altText.textContent = msg;
|
|
||||||
altText.setAttribute("aria-label", msg);
|
|
||||||
altText.tabIndex = "0";
|
|
||||||
altText.addEventListener("contextmenu", noContextMenu);
|
|
||||||
altText.addEventListener("pointerdown", event => event.stopPropagation());
|
|
||||||
|
|
||||||
const onClick = event => {
|
|
||||||
this.#altTextButton.hidden = true;
|
|
||||||
event.preventDefault();
|
|
||||||
this._uiManager.editAltText(this);
|
|
||||||
};
|
|
||||||
altText.addEventListener("click", onClick, { capture: true });
|
|
||||||
altText.addEventListener("keydown", event => {
|
|
||||||
if (event.target === altText && event.key === "Enter") {
|
|
||||||
this.#altTextWasFromKeyBoard = true;
|
|
||||||
onClick(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.#setAltTextButtonState();
|
|
||||||
this.div.append(altText);
|
|
||||||
if (!AnnotationEditor.SMALL_EDITOR_SIZE) {
|
|
||||||
// We take the width of the alt text button and we add 40% to it to be
|
|
||||||
// sure to have enough space for it.
|
|
||||||
const PERCENT = 40;
|
|
||||||
AnnotationEditor.SMALL_EDITOR_SIZE = Math.min(
|
|
||||||
128,
|
|
||||||
Math.round(altText.getBoundingClientRect().width * (1 + PERCENT / 100))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async #setAltTextButtonState() {
|
|
||||||
const button = this.#altTextButton;
|
|
||||||
if (!button) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!this.#altText && !this.#altTextDecorative) {
|
|
||||||
button.classList.remove("done");
|
|
||||||
this.#altTextTooltip?.remove();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
button.classList.add("done");
|
|
||||||
|
|
||||||
AnnotationEditor._l10nPromise
|
|
||||||
.get("pdfjs-editor-alt-text-edit-button-label")
|
|
||||||
.then(msg => {
|
|
||||||
button.setAttribute("aria-label", msg);
|
|
||||||
});
|
|
||||||
let tooltip = this.#altTextTooltip;
|
|
||||||
if (!tooltip) {
|
|
||||||
this.#altTextTooltip = tooltip = document.createElement("span");
|
|
||||||
tooltip.className = "tooltip";
|
|
||||||
tooltip.setAttribute("role", "tooltip");
|
|
||||||
const id = (tooltip.id = `alt-text-tooltip-${this.id}`);
|
|
||||||
button.setAttribute("aria-describedby", id);
|
|
||||||
|
|
||||||
const DELAY_TO_SHOW_TOOLTIP = 100;
|
|
||||||
button.addEventListener("mouseenter", () => {
|
|
||||||
this.#altTextTooltipTimeout = setTimeout(() => {
|
|
||||||
this.#altTextTooltipTimeout = null;
|
|
||||||
this.#altTextTooltip.classList.add("show");
|
|
||||||
this._uiManager._eventBus.dispatch("reporttelemetry", {
|
|
||||||
source: this,
|
|
||||||
details: {
|
|
||||||
type: "editing",
|
|
||||||
subtype: this.editorType,
|
|
||||||
data: {
|
|
||||||
action: "alt_text_tooltip",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}, DELAY_TO_SHOW_TOOLTIP);
|
|
||||||
});
|
|
||||||
button.addEventListener("mouseleave", () => {
|
|
||||||
if (this.#altTextTooltipTimeout) {
|
|
||||||
clearTimeout(this.#altTextTooltipTimeout);
|
|
||||||
this.#altTextTooltipTimeout = null;
|
|
||||||
}
|
|
||||||
this.#altTextTooltip?.classList.remove("show");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
tooltip.innerText = this.#altTextDecorative
|
|
||||||
? await AnnotationEditor._l10nPromise.get(
|
|
||||||
"pdfjs-editor-alt-text-decorative-tooltip"
|
|
||||||
)
|
|
||||||
: this.#altText;
|
|
||||||
|
|
||||||
if (!tooltip.parentNode) {
|
|
||||||
button.append(tooltip);
|
|
||||||
}
|
|
||||||
|
|
||||||
const element = this.getImageForAltText();
|
|
||||||
element?.setAttribute("aria-describedby", tooltip.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
#toggleAltTextButton(enabled = false) {
|
|
||||||
if (!this.#altTextButton) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!enabled && this.#altTextTooltipTimeout) {
|
|
||||||
clearTimeout(this.#altTextTooltipTimeout);
|
|
||||||
this.#altTextTooltipTimeout = null;
|
|
||||||
}
|
|
||||||
this.#altTextButton.disabled = !enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
altTextFinish() {
|
altTextFinish() {
|
||||||
if (!this.#altTextButton) {
|
this.#altText?.finish();
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.#altTextButton.hidden = false;
|
|
||||||
this.#altTextButton.focus({ focusVisible: this.#altTextWasFromKeyBoard });
|
|
||||||
this.#altTextWasFromKeyBoard = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addEditToolbar() {
|
async addEditToolbar() {
|
||||||
if (this.#editToolbar || this.#isInEditMode) {
|
if (this.#editToolbar || this.#isInEditMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.#editToolbar = new EditorToolbar(this);
|
this.#editToolbar = new EditorToolbar(this);
|
||||||
this.div.append(this.#editToolbar.render());
|
this.div.append(this.#editToolbar.render());
|
||||||
|
if (this.#altText) {
|
||||||
|
this.#editToolbar.addAltTextButton(await this.#altText.render());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeEditToolbar() {
|
removeEditToolbar() {
|
||||||
@ -1055,29 +920,37 @@ class AnnotationEditor {
|
|||||||
}
|
}
|
||||||
this.#editToolbar.remove();
|
this.#editToolbar.remove();
|
||||||
this.#editToolbar = null;
|
this.#editToolbar = null;
|
||||||
|
|
||||||
|
// We destroy the alt text but we don't null it because we want to be able
|
||||||
|
// to restore it in case the user undoes the deletion.
|
||||||
|
this.#altText?.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
getClientDimensions() {
|
getClientDimensions() {
|
||||||
return this.div.getBoundingClientRect();
|
return this.div.getBoundingClientRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async addAltTextButton() {
|
||||||
|
if (this.#altText) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AltText.initialize(AnnotationEditor._l10nPromise);
|
||||||
|
this.#altText = new AltText(this);
|
||||||
|
await this.addEditToolbar();
|
||||||
|
}
|
||||||
|
|
||||||
get altTextData() {
|
get altTextData() {
|
||||||
return {
|
return this.#altText?.data;
|
||||||
altText: this.#altText,
|
|
||||||
decorative: this.#altTextDecorative,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the alt text data.
|
* Set the alt text data.
|
||||||
*/
|
*/
|
||||||
set altTextData({ altText, decorative }) {
|
set altTextData(data) {
|
||||||
if (this.#altText === altText && this.#altTextDecorative === decorative) {
|
if (!this.#altText) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.#altText = altText;
|
this.#altText.data = data;
|
||||||
this.#altTextDecorative = decorative;
|
|
||||||
this.#setAltTextButtonState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1413,11 +1286,6 @@ class AnnotationEditor {
|
|||||||
this._uiManager.removeEditor(this);
|
this._uiManager.removeEditor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The editor is removed so we can remove the alt text button and if it's
|
|
||||||
// restored then it's up to the subclass to add it back.
|
|
||||||
this.#altTextButton?.remove();
|
|
||||||
this.#altTextButton = null;
|
|
||||||
this.#altTextTooltip = null;
|
|
||||||
if (this.#moveInDOMTimeout) {
|
if (this.#moveInDOMTimeout) {
|
||||||
clearTimeout(this.#moveInDOMTimeout);
|
clearTimeout(this.#moveInDOMTimeout);
|
||||||
this.#moveInDOMTimeout = null;
|
this.#moveInDOMTimeout = null;
|
||||||
@ -1585,7 +1453,17 @@ class AnnotationEditor {
|
|||||||
select() {
|
select() {
|
||||||
this.makeResizable();
|
this.makeResizable();
|
||||||
this.div?.classList.add("selectedEditor");
|
this.div?.classList.add("selectedEditor");
|
||||||
this.addEditToolbar();
|
if (!this.#editToolbar) {
|
||||||
|
this.addEditToolbar().then(() => {
|
||||||
|
if (this.div?.classList.contains("selectedEditor")) {
|
||||||
|
// The editor can have been unselected while we were waiting for the
|
||||||
|
// edit toolbar to be created, hence we want to be sure that this
|
||||||
|
// editor is still selected.
|
||||||
|
this.#editToolbar?.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.#editToolbar?.show();
|
this.#editToolbar?.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1614,21 +1492,13 @@ class AnnotationEditor {
|
|||||||
* When the user disables the editing mode some editors can change some of
|
* When the user disables the editing mode some editors can change some of
|
||||||
* their properties.
|
* their properties.
|
||||||
*/
|
*/
|
||||||
disableEditing() {
|
disableEditing() {}
|
||||||
if (this.#altTextButton) {
|
|
||||||
this.#altTextButton.hidden = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the user enables the editing mode some editors can change some of
|
* When the user enables the editing mode some editors can change some of
|
||||||
* their properties.
|
* their properties.
|
||||||
*/
|
*/
|
||||||
enableEditing() {
|
enableEditing() {}
|
||||||
if (this.#altTextButton) {
|
|
||||||
this.#altTextButton.hidden = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The editor is about to be edited.
|
* The editor is about to be edited.
|
||||||
|
@ -95,7 +95,10 @@ class EditorToolbar {
|
|||||||
const button = document.createElement("button");
|
const button = document.createElement("button");
|
||||||
button.className = "delete";
|
button.className = "delete";
|
||||||
button.tabIndex = 0;
|
button.tabIndex = 0;
|
||||||
button.setAttribute("data-l10n-id", "pdfjs-editor-remove-button");
|
button.setAttribute(
|
||||||
|
"data-l10n-id",
|
||||||
|
`pdfjs-editor-remove-${this.#editor.editorType}-button`
|
||||||
|
);
|
||||||
this.#addListenersToElement(button);
|
this.#addListenersToElement(button);
|
||||||
button.addEventListener("click", e => {
|
button.addEventListener("click", e => {
|
||||||
this.#editor._uiManager.delete();
|
this.#editor._uiManager.delete();
|
||||||
@ -103,6 +106,17 @@ class EditorToolbar {
|
|||||||
this.#buttons.append(button);
|
this.#buttons.append(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addAltTextButton(button) {
|
||||||
|
this.#addListenersToElement(button);
|
||||||
|
this.#buttons.prepend(button, this.#divider);
|
||||||
|
}
|
||||||
|
|
||||||
|
get #divider() {
|
||||||
|
const divider = document.createElement("div");
|
||||||
|
divider.className = "divider";
|
||||||
|
return divider;
|
||||||
|
}
|
||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
this.#toolbar.remove();
|
this.#toolbar.remove();
|
||||||
}
|
}
|
||||||
|
@ -293,9 +293,6 @@ describe("Stamp Editor", () => {
|
|||||||
// Click on the alt-text button.
|
// Click on the alt-text button.
|
||||||
await page.click(buttonSelector);
|
await page.click(buttonSelector);
|
||||||
|
|
||||||
// Check that the alt-text button has been hidden.
|
|
||||||
await page.waitForSelector(`${buttonSelector}[hidden]`);
|
|
||||||
|
|
||||||
// Wait for the alt-text dialog to be visible.
|
// Wait for the alt-text dialog to be visible.
|
||||||
await page.waitForSelector("#altTextDialog", { visible: true });
|
await page.waitForSelector("#altTextDialog", { visible: true });
|
||||||
|
|
||||||
@ -314,7 +311,7 @@ describe("Stamp Editor", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Wait for the alt-text button to have the correct icon.
|
// Wait for the alt-text button to have the correct icon.
|
||||||
await page.waitForSelector(`${buttonSelector}:not([hidden]).done`);
|
await page.waitForSelector(`${buttonSelector}.done`);
|
||||||
|
|
||||||
// Hover the button.
|
// Hover the button.
|
||||||
await page.hover(buttonSelector);
|
await page.hover(buttonSelector);
|
||||||
@ -427,10 +424,8 @@ describe("Stamp Editor", () => {
|
|||||||
? page.waitForSelector(`${buttonSelector}:focus`)
|
? page.waitForSelector(`${buttonSelector}:focus`)
|
||||||
: page.waitForSelector(`${buttonSelector}:focus-visible`));
|
: page.waitForSelector(`${buttonSelector}:focus-visible`));
|
||||||
await page.keyboard.press("Enter");
|
await page.keyboard.press("Enter");
|
||||||
await page.waitForSelector(`${buttonSelector}[hidden]`);
|
|
||||||
await page.waitForSelector("#altTextDialog", { visible: true });
|
await page.waitForSelector("#altTextDialog", { visible: true });
|
||||||
await page.keyboard.press("Escape");
|
await page.keyboard.press("Escape");
|
||||||
await page.waitForSelector(`${buttonSelector}:not([hidden])`);
|
|
||||||
await (browserName === "chrome"
|
await (browserName === "chrome"
|
||||||
? page.waitForSelector(`${buttonSelector}:focus`)
|
? page.waitForSelector(`${buttonSelector}:focus`)
|
||||||
: page.waitForSelector(`${buttonSelector}:focus-visible`));
|
: page.waitForSelector(`${buttonSelector}:focus-visible`));
|
||||||
|
@ -43,22 +43,6 @@
|
|||||||
/*#else*/
|
/*#else*/
|
||||||
--editorInk-editing-cursor: url(images/cursor-editorInk.svg) 0 16, pointer;
|
--editorInk-editing-cursor: url(images/cursor-editorInk.svg) 0 16, pointer;
|
||||||
/*#endif*/
|
/*#endif*/
|
||||||
|
|
||||||
--alt-text-opacity: 0.8;
|
|
||||||
--alt-text-add-image: url(images/altText_add.svg);
|
|
||||||
--alt-text-done-image: url(images/altText_done.svg);
|
|
||||||
--alt-text-bg-color: rgb(43 42 51 / var(--alt-text-opacity));
|
|
||||||
--alt-text-fg-color: #fbfbfe;
|
|
||||||
--alt-text-border-color: var(--alt-text-bg-color);
|
|
||||||
--alt-text-hover-bg-color: rgb(82 82 94 / var(--alt-text-opacity));
|
|
||||||
--alt-text-hover-fg-color: var(--alt-text-fg-color);
|
|
||||||
--alt-text-hover-border-color: var(--alt-text-hover-bg-color);
|
|
||||||
--alt-text-active-bg-color: rgb(91 91 102 / var(--alt-text-opacity));
|
|
||||||
--alt-text-active-fg-color: var(--alt-text-fg-color);
|
|
||||||
--alt-text-active-border-color: var(--alt-text-hover-bg-color);
|
|
||||||
--alt-text-focus-outline-color: #0060df;
|
|
||||||
--alt-text-focus-border-color: #f0f0f4;
|
|
||||||
--alt-text-shadow: 0 2px 6px 0 rgb(28 27 34 / 0.5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-resolution: 1.1dppx) {
|
@media (min-resolution: 1.1dppx) {
|
||||||
@ -77,29 +61,17 @@
|
|||||||
--resizer-bg-color: ButtonText;
|
--resizer-bg-color: ButtonText;
|
||||||
--hover-outline-color: Highlight;
|
--hover-outline-color: Highlight;
|
||||||
--hover-outline-around-color: SelectedItemText;
|
--hover-outline-around-color: SelectedItemText;
|
||||||
|
|
||||||
--alt-text-bg-color: Canvas;
|
|
||||||
--alt-text-fg-color: ButtonText;
|
|
||||||
--alt-text-border-color: ButtonText;
|
|
||||||
--alt-text-hover-bg-color: Canvas;
|
|
||||||
--alt-text-hover-fg-color: SelectedItem;
|
|
||||||
--alt-text-hover-border-color: SelectedItem;
|
|
||||||
--alt-text-active-bg-color: ButtonFace;
|
|
||||||
--alt-text-active-fg-color: SelectedItem;
|
|
||||||
--alt-text-active-border-color: ButtonText;
|
|
||||||
--alt-text-focus-outline-color: CanvasText;
|
|
||||||
--alt-text-focus-border-color: ButtonText;
|
|
||||||
--alt-text-shadow: none;
|
|
||||||
--alt-text-opacity: 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-editor-rotation="90"] {
|
[data-editor-rotation="90"] {
|
||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-editor-rotation="180"] {
|
[data-editor-rotation="180"] {
|
||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-editor-rotation="270"] {
|
[data-editor-rotation="270"] {
|
||||||
transform: rotate(270deg);
|
transform: rotate(270deg);
|
||||||
}
|
}
|
||||||
@ -204,11 +176,12 @@
|
|||||||
--editor-toolbar-focus-outline-color: #0060df;
|
--editor-toolbar-focus-outline-color: #0060df;
|
||||||
--editor-toolbar-shadow: 0 2px 6px 0 rgb(58 57 68 / 0.2);
|
--editor-toolbar-shadow: 0 2px 6px 0 rgb(58 57 68 / 0.2);
|
||||||
--editor-toolbar-vert-offset: 6px;
|
--editor-toolbar-vert-offset: 6px;
|
||||||
|
--editor-toolbar-height: 28px;
|
||||||
|
--editor-toolbar-padding: 2px;
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
--editor-toolbar-bg-color: #2b2a33;
|
--editor-toolbar-bg-color: #2b2a33;
|
||||||
--editor-toolbar-fg-color: #fbfbfe;
|
--editor-toolbar-fg-color: #fbfbfe;
|
||||||
--editor-toolbar-border-color: #2b2a33;
|
|
||||||
--editor-toolbar-hover-bg-color: #52525e;
|
--editor-toolbar-hover-bg-color: #52525e;
|
||||||
--editor-toolbar-active-bg-color: #5b5b66;
|
--editor-toolbar-active-bg-color: #5b5b66;
|
||||||
--editor-toolbar-focus-outline-color: #0df;
|
--editor-toolbar-focus-outline-color: #0df;
|
||||||
@ -226,18 +199,20 @@
|
|||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
height: 28px;
|
height: var(--editor-toolbar-height);
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
|
box-sizing: content-box;
|
||||||
|
padding: var(--editor-toolbar-padding);
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset-inline-end: 0;
|
inset-inline-end: 0;
|
||||||
inset-block-start: calc(100% + var(--editor-toolbar-vert-offset));
|
inset-block-start: calc(100% + var(--editor-toolbar-vert-offset));
|
||||||
|
|
||||||
border-radius: 4px;
|
border-radius: 6px;
|
||||||
background-color: var(--editor-toolbar-bg-color);
|
background-color: var(--editor-toolbar-bg-color);
|
||||||
border: 1px solid var(--editor-toolbar-border-color);
|
border: 1px solid var(--editor-toolbar-border-color);
|
||||||
box-shadow: var(--editor-toolbar-shadow);
|
box-shadow: var(--editor-toolbar-shadow);
|
||||||
@ -250,19 +225,33 @@
|
|||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:dir(ltr) {
|
||||||
|
transform-origin: 100% 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:dir(rtl) {
|
||||||
|
transform-origin: 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
.buttons {
|
.buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 0 2px;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 0;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
width: 1px;
|
||||||
|
height: calc(
|
||||||
|
2 * var(--editor-toolbar-padding) + var(--editor-toolbar-height)
|
||||||
|
);
|
||||||
|
background-color: var(--editor-toolbar-border-color);
|
||||||
|
display: inline-block;
|
||||||
|
margin-inline: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
.delete {
|
.delete {
|
||||||
width: 24px;
|
width: var(--editor-toolbar-height);
|
||||||
height: 24px;
|
|
||||||
cursor: pointer;
|
|
||||||
border: none;
|
|
||||||
background-color: transparent;
|
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
content: "";
|
content: "";
|
||||||
@ -277,6 +266,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
|
height: var(--editor-toolbar-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
> :not(.divider) {
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
background-color: var(--editor-toolbar-hover-bg-color);
|
background-color: var(--editor-toolbar-hover-bg-color);
|
||||||
@ -288,10 +285,91 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
border-radius: 3px;
|
border-radius: 2px;
|
||||||
outline: 2px solid var(--editor-toolbar-focus-outline-color);
|
outline: 2px solid var(--editor-toolbar-focus-outline-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.altText {
|
||||||
|
--alt-text-add-image: url(images/altText_add.svg);
|
||||||
|
--alt-text-done-image: url(images/altText_done.svg);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: max-content;
|
||||||
|
padding-inline: 8px;
|
||||||
|
pointer-events: all;
|
||||||
|
font: menu;
|
||||||
|
font-weight: 590;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--editor-toolbar-fg-color);
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
mask-image: var(--alt-text-add-image);
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center;
|
||||||
|
display: inline-block;
|
||||||
|
width: 12px;
|
||||||
|
height: 13px;
|
||||||
|
background-color: var(--editor-toolbar-fg-color);
|
||||||
|
margin-inline-end: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.done::before {
|
||||||
|
mask-image: var(--alt-text-done-image);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
&.show {
|
||||||
|
--alt-text-tooltip-bg: #f0f0f4;
|
||||||
|
--alt-text-tooltip-fg: #15141a;
|
||||||
|
--alt-text-tooltip-border: #8f8f9d;
|
||||||
|
--alt-text-tooltip-shadow: 0px 2px 6px 0px rgb(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -494,40 +572,17 @@
|
|||||||
[data-main-rotation="180"] [data-editor-rotation="270"],
|
[data-main-rotation="180"] [data-editor-rotation="270"],
|
||||||
[data-main-rotation="270"] [data-editor-rotation="180"]
|
[data-main-rotation="270"] [data-editor-rotation="180"]
|
||||||
) {
|
) {
|
||||||
& .altText {
|
|
||||||
rotate: 270deg;
|
|
||||||
|
|
||||||
&:dir(ltr) {
|
|
||||||
inset-inline-start: calc(100% - 8px);
|
|
||||||
|
|
||||||
&.small {
|
|
||||||
inset-inline-start: calc(100% + 8px);
|
|
||||||
inset-block-start: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:dir(rtl) {
|
|
||||||
inset-block-end: calc(100% - 8px);
|
|
||||||
|
|
||||||
&.small {
|
|
||||||
inset-inline-start: -8px;
|
|
||||||
inset-block-start: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.editToolbar {
|
.editToolbar {
|
||||||
rotate: 270deg;
|
rotate: 270deg;
|
||||||
|
|
||||||
&:dir(ltr) {
|
&:dir(ltr) {
|
||||||
inset-inline-start: calc(100% + var(--editor-toolbar-vert-offset));
|
inset-inline-end: calc(0px - var(--editor-toolbar-vert-offset));
|
||||||
inset-block-start: 0;
|
inset-block-start: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:dir(rtl) {
|
&:dir(rtl) {
|
||||||
inset-inline-end: calc(100% + var(--editor-toolbar-vert-offset));
|
inset-inline-end: calc(100% + var(--editor-toolbar-vert-offset));
|
||||||
inset-block-end: 0;
|
inset-block-start: 0;
|
||||||
inset-block-start: unset;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -539,23 +594,10 @@
|
|||||||
[data-main-rotation="180"] [data-editor-rotation="0"],
|
[data-main-rotation="180"] [data-editor-rotation="0"],
|
||||||
[data-main-rotation="270"] [data-editor-rotation="270"]
|
[data-main-rotation="270"] [data-editor-rotation="270"]
|
||||||
) {
|
) {
|
||||||
& .altText {
|
|
||||||
rotate: 180deg;
|
|
||||||
|
|
||||||
inset-block-end: calc(100% - 8px);
|
|
||||||
inset-inline-start: calc(100% - 8px);
|
|
||||||
|
|
||||||
&.small {
|
|
||||||
inset-inline-start: 100%;
|
|
||||||
inset-block-start: -8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.editToolbar {
|
.editToolbar {
|
||||||
rotate: 180deg;
|
rotate: 180deg;
|
||||||
inset-inline-start: 0;
|
inset-inline-end: 100%;
|
||||||
inset-block-end: calc(100% + var(--editor-toolbar-vert-offset));
|
inset-block-start: calc(0pc - var(--editor-toolbar-vert-offset));
|
||||||
inset-block-start: unset;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -566,182 +608,22 @@
|
|||||||
[data-main-rotation="180"] [data-editor-rotation="90"],
|
[data-main-rotation="180"] [data-editor-rotation="90"],
|
||||||
[data-main-rotation="270"] [data-editor-rotation="0"]
|
[data-main-rotation="270"] [data-editor-rotation="0"]
|
||||||
) {
|
) {
|
||||||
& .altText {
|
|
||||||
rotate: 90deg;
|
|
||||||
|
|
||||||
&:dir(ltr) {
|
|
||||||
inset-block-end: calc(100% - 8px);
|
|
||||||
|
|
||||||
&.small {
|
|
||||||
inset-inline-start: -8px;
|
|
||||||
inset-block-start: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:dir(rtl) {
|
|
||||||
inset-inline-start: calc(100% - 8px);
|
|
||||||
|
|
||||||
&.small {
|
|
||||||
inset-inline-start: calc(100% + 8px);
|
|
||||||
inset-block-start: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.editToolbar {
|
.editToolbar {
|
||||||
rotate: 90deg;
|
rotate: 90deg;
|
||||||
|
|
||||||
&:dir(ltr) {
|
&:dir(ltr) {
|
||||||
inset-inline-end: calc(100% + var(--editor-toolbar-vert-offset));
|
inset-inline-end: calc(100% + var(--editor-toolbar-vert-offset));
|
||||||
inset-block-end: 0;
|
inset-block-start: 100%;
|
||||||
inset-block-start: unset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:dir(rtl) {
|
&:dir(rtl) {
|
||||||
inset-inline-start: calc(100% + var(--editor-toolbar-vert-offset));
|
inset-inline-start: calc(0px - var(--editor-toolbar-vert-offset));
|
||||||
inset-block-start: 0;
|
inset-block-start: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.altText {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding-inline: 4px;
|
|
||||||
width: max-content;
|
|
||||||
height: 24px;
|
|
||||||
min-width: 88px;
|
|
||||||
z-index: 1;
|
|
||||||
pointer-events: all;
|
|
||||||
|
|
||||||
color: var(--alt-text-fg-color);
|
|
||||||
font: menu;
|
|
||||||
font-size: 12px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid var(--alt-text-border-color);
|
|
||||||
background-color: var(--alt-text-bg-color);
|
|
||||||
box-shadow: var(--alt-text-shadow);
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
inset-block-end: 8px;
|
|
||||||
inset-inline-start: 8px;
|
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:dir(ltr) {
|
|
||||||
transform-origin: 0 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:dir(rtl) {
|
|
||||||
transform-origin: 100% 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.small {
|
|
||||||
&:dir(ltr) {
|
|
||||||
transform-origin: 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:dir(rtl) {
|
|
||||||
transform-origin: 100% 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inset-block-end: unset;
|
|
||||||
inset-inline-start: 0;
|
|
||||||
inset-block-start: calc(100% + 8px);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--alt-text-hover-bg-color);
|
|
||||||
border-color: var(--alt-text-hover-border-color);
|
|
||||||
color: var(--alt-text-hover-fg-color);
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
background-color: var(--alt-text-hover-fg-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: var(--alt-text-active-bg-color);
|
|
||||||
border-color: var(--alt-text-active-border-color);
|
|
||||||
color: var(--alt-text-active-fg-color);
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
background-color: var(--alt-text-active-fg-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus-visible {
|
|
||||||
outline: 2px solid var(--alt-text-focus-outline-color);
|
|
||||||
border-color: var(--alt-text-focus-border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: "";
|
|
||||||
mask-image: var(--alt-text-add-image);
|
|
||||||
mask-repeat: no-repeat;
|
|
||||||
mask-position: center;
|
|
||||||
display: inline-block;
|
|
||||||
width: 12px;
|
|
||||||
height: 13px;
|
|
||||||
background-color: var(--alt-text-fg-color);
|
|
||||||
margin-inline-end: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.done::before {
|
|
||||||
mask-image: var(--alt-text-done-image);
|
|
||||||
}
|
|
||||||
|
|
||||||
& .tooltip {
|
|
||||||
display: none;
|
|
||||||
|
|
||||||
&.show {
|
|
||||||
--alt-text-tooltip-bg: #f0f0f4;
|
|
||||||
--alt-text-tooltip-fg: #15141a;
|
|
||||||
--alt-text-tooltip-border: #8f8f9d;
|
|
||||||
--alt-text-tooltip-shadow: 0px 2px 6px 0px rgb(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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#altTextDialog {
|
#altTextDialog {
|
||||||
--dialog-bg-color: white;
|
--dialog-bg-color: white;
|
||||||
--dialog-border-color: white;
|
--dialog-border-color: white;
|
||||||
@ -1062,7 +944,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.editToolbar {
|
.editToolbar {
|
||||||
transform-origin: center;
|
transform-origin: center !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user