Merge pull request #16987 from calixteman/alt_text_telemetry
[Editor] Add more telemetry for the 'add image' feature (bug 1853960)
This commit is contained in:
commit
0317d3e168
@ -119,6 +119,10 @@ class AnnotationEditor {
|
|||||||
this.deleted = false;
|
this.deleted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get editorType() {
|
||||||
|
return Object.getPrototypeOf(this).constructor._type;
|
||||||
|
}
|
||||||
|
|
||||||
static get _defaultLineColor() {
|
static get _defaultLineColor() {
|
||||||
return shadow(
|
return shadow(
|
||||||
this,
|
this,
|
||||||
@ -843,18 +847,6 @@ 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) {
|
||||||
@ -881,6 +873,29 @@ class AnnotationEditor {
|
|||||||
const id = (tooltip.id = `alt-text-tooltip-${this.id}`);
|
const id = (tooltip.id = `alt-text-tooltip-${this.id}`);
|
||||||
button.append(tooltip);
|
button.append(tooltip);
|
||||||
button.setAttribute("aria-describedby", id);
|
button.setAttribute("aria-describedby", id);
|
||||||
|
|
||||||
|
const DELAY_TO_SHOW_TOOLTIP = 500;
|
||||||
|
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", () => {
|
||||||
|
clearTimeout(this.#altTextTooltipTimeout);
|
||||||
|
this.#altTextTooltipTimeout = null;
|
||||||
|
this.#altTextTooltip?.classList.remove("show");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
button.classList.add("done");
|
button.classList.add("done");
|
||||||
if (this.#altTextDecorative) {
|
if (this.#altTextDecorative) {
|
||||||
|
@ -311,6 +311,20 @@ class StampEditor extends AnnotationEditor {
|
|||||||
this.parent.addUndoableEditor(this);
|
this.parent.addUndoableEditor(this);
|
||||||
this.#hasBeenAddedInUndoStack = true;
|
this.#hasBeenAddedInUndoStack = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// There are multiple ways to add an image to the page, so here we just
|
||||||
|
// count the number of times an image is added to the page whatever the way
|
||||||
|
// is.
|
||||||
|
this._uiManager._eventBus.dispatch("reporttelemetry", {
|
||||||
|
source: this,
|
||||||
|
details: {
|
||||||
|
type: "editing",
|
||||||
|
subtype: this.editorType,
|
||||||
|
data: {
|
||||||
|
action: "inserted_image",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
this.addAltTextButton();
|
this.addAltTextButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,8 +541,6 @@ class AnnotationEditorUIManager {
|
|||||||
|
|
||||||
#editorsToRescale = new Set();
|
#editorsToRescale = new Set();
|
||||||
|
|
||||||
#eventBus = null;
|
|
||||||
|
|
||||||
#filterFactory = null;
|
#filterFactory = null;
|
||||||
|
|
||||||
#idManager = new IdManager();
|
#idManager = new IdManager();
|
||||||
@ -706,11 +704,11 @@ class AnnotationEditorUIManager {
|
|||||||
this.#container = container;
|
this.#container = container;
|
||||||
this.#viewer = viewer;
|
this.#viewer = viewer;
|
||||||
this.#altTextManager = altTextManager;
|
this.#altTextManager = altTextManager;
|
||||||
this.#eventBus = eventBus;
|
this._eventBus = eventBus;
|
||||||
this.#eventBus._on("editingaction", this.#boundOnEditingAction);
|
this._eventBus._on("editingaction", this.#boundOnEditingAction);
|
||||||
this.#eventBus._on("pagechanging", this.#boundOnPageChanging);
|
this._eventBus._on("pagechanging", this.#boundOnPageChanging);
|
||||||
this.#eventBus._on("scalechanging", this.#boundOnScaleChanging);
|
this._eventBus._on("scalechanging", this.#boundOnScaleChanging);
|
||||||
this.#eventBus._on("rotationchanging", this.#boundOnRotationChanging);
|
this._eventBus._on("rotationchanging", this.#boundOnRotationChanging);
|
||||||
this.#annotationStorage = pdfDocument.annotationStorage;
|
this.#annotationStorage = pdfDocument.annotationStorage;
|
||||||
this.#filterFactory = pdfDocument.filterFactory;
|
this.#filterFactory = pdfDocument.filterFactory;
|
||||||
this.#pageColors = pageColors;
|
this.#pageColors = pageColors;
|
||||||
@ -723,10 +721,10 @@ class AnnotationEditorUIManager {
|
|||||||
destroy() {
|
destroy() {
|
||||||
this.#removeKeyboardManager();
|
this.#removeKeyboardManager();
|
||||||
this.#removeFocusManager();
|
this.#removeFocusManager();
|
||||||
this.#eventBus._off("editingaction", this.#boundOnEditingAction);
|
this._eventBus._off("editingaction", this.#boundOnEditingAction);
|
||||||
this.#eventBus._off("pagechanging", this.#boundOnPageChanging);
|
this._eventBus._off("pagechanging", this.#boundOnPageChanging);
|
||||||
this.#eventBus._off("scalechanging", this.#boundOnScaleChanging);
|
this._eventBus._off("scalechanging", this.#boundOnScaleChanging);
|
||||||
this.#eventBus._off("rotationchanging", this.#boundOnRotationChanging);
|
this._eventBus._off("rotationchanging", this.#boundOnRotationChanging);
|
||||||
for (const layer of this.#allLayers.values()) {
|
for (const layer of this.#allLayers.values()) {
|
||||||
layer.destroy();
|
layer.destroy();
|
||||||
}
|
}
|
||||||
@ -1041,7 +1039,7 @@ class AnnotationEditorUIManager {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (hasChanged) {
|
if (hasChanged) {
|
||||||
this.#eventBus.dispatch("annotationeditorstateschanged", {
|
this._eventBus.dispatch("annotationeditorstateschanged", {
|
||||||
source: this,
|
source: this,
|
||||||
details: Object.assign(this.#previousStates, details),
|
details: Object.assign(this.#previousStates, details),
|
||||||
});
|
});
|
||||||
@ -1049,7 +1047,7 @@ class AnnotationEditorUIManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#dispatchUpdateUI(details) {
|
#dispatchUpdateUI(details) {
|
||||||
this.#eventBus.dispatch("annotationeditorparamschanged", {
|
this._eventBus.dispatch("annotationeditorparamschanged", {
|
||||||
source: this,
|
source: this,
|
||||||
details,
|
details,
|
||||||
});
|
});
|
||||||
@ -1177,7 +1175,7 @@ class AnnotationEditorUIManager {
|
|||||||
if (mode === this.#mode) {
|
if (mode === this.#mode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.#eventBus.dispatch("switchannotationeditormode", {
|
this._eventBus.dispatch("switchannotationeditormode", {
|
||||||
source: this,
|
source: this,
|
||||||
mode,
|
mode,
|
||||||
});
|
});
|
||||||
|
@ -13,16 +13,24 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { shadow } from "pdfjs-lib";
|
||||||
|
|
||||||
class AltTextManager {
|
class AltTextManager {
|
||||||
#boundUpdateUIState = this.#updateUIState.bind(this);
|
#boundUpdateUIState = this.#updateUIState.bind(this);
|
||||||
|
|
||||||
#boundSetPosition = this.#setPosition.bind(this);
|
#boundSetPosition = this.#setPosition.bind(this);
|
||||||
|
|
||||||
|
#boundPointerDown = this.#pointerDown.bind(this);
|
||||||
|
|
||||||
#currentEditor = null;
|
#currentEditor = null;
|
||||||
|
|
||||||
|
#cancelButton;
|
||||||
|
|
||||||
#dialog;
|
#dialog;
|
||||||
|
|
||||||
#eventBus = null;
|
#eventBus;
|
||||||
|
|
||||||
|
#hasUsedPointer = false;
|
||||||
|
|
||||||
#optionDescription;
|
#optionDescription;
|
||||||
|
|
||||||
@ -36,6 +44,8 @@ class AltTextManager {
|
|||||||
|
|
||||||
#uiManager;
|
#uiManager;
|
||||||
|
|
||||||
|
#previousAltText = null;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
{
|
{
|
||||||
dialog,
|
dialog,
|
||||||
@ -52,12 +62,13 @@ class AltTextManager {
|
|||||||
this.#optionDescription = optionDescription;
|
this.#optionDescription = optionDescription;
|
||||||
this.#optionDecorative = optionDecorative;
|
this.#optionDecorative = optionDecorative;
|
||||||
this.#textarea = textarea;
|
this.#textarea = textarea;
|
||||||
|
this.#cancelButton = cancelButton;
|
||||||
this.#saveButton = saveButton;
|
this.#saveButton = saveButton;
|
||||||
this.#overlayManager = overlayManager;
|
this.#overlayManager = overlayManager;
|
||||||
this.#eventBus = eventBus;
|
this.#eventBus = eventBus;
|
||||||
|
|
||||||
dialog.addEventListener("close", this.#close.bind(this));
|
dialog.addEventListener("close", this.#close.bind(this));
|
||||||
cancelButton.addEventListener("click", this.#finish.bind(this));
|
cancelButton.addEventListener("click", this.#cancel.bind(this));
|
||||||
saveButton.addEventListener("click", this.#save.bind(this));
|
saveButton.addEventListener("click", this.#save.bind(this));
|
||||||
optionDescription.addEventListener("change", this.#boundUpdateUIState);
|
optionDescription.addEventListener("change", this.#boundUpdateUIState);
|
||||||
optionDecorative.addEventListener("change", this.#boundUpdateUIState);
|
optionDecorative.addEventListener("change", this.#boundUpdateUIState);
|
||||||
@ -66,11 +77,26 @@ class AltTextManager {
|
|||||||
this.#overlayManager.register(dialog);
|
this.#overlayManager.register(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get _elements() {
|
||||||
|
return shadow(this, "_elements", [
|
||||||
|
this.#optionDescription,
|
||||||
|
this.#optionDecorative,
|
||||||
|
this.#textarea,
|
||||||
|
this.#saveButton,
|
||||||
|
this.#cancelButton,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
async editAltText(uiManager, editor) {
|
async editAltText(uiManager, editor) {
|
||||||
if (this.#currentEditor || !editor) {
|
if (this.#currentEditor || !editor) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.#hasUsedPointer = false;
|
||||||
|
for (const element of this._elements) {
|
||||||
|
element.addEventListener("pointerdown", this.#boundPointerDown);
|
||||||
|
}
|
||||||
|
|
||||||
const { altText, decorative } = editor.altTextData;
|
const { altText, decorative } = editor.altTextData;
|
||||||
if (decorative === true) {
|
if (decorative === true) {
|
||||||
this.#optionDecorative.checked = true;
|
this.#optionDecorative.checked = true;
|
||||||
@ -79,7 +105,7 @@ class AltTextManager {
|
|||||||
this.#optionDecorative.checked = false;
|
this.#optionDecorative.checked = false;
|
||||||
this.#optionDescription.checked = true;
|
this.#optionDescription.checked = true;
|
||||||
}
|
}
|
||||||
this.#textarea.value = altText?.trim() || "";
|
this.#previousAltText = this.#textarea.value = altText?.trim() || "";
|
||||||
this.#updateUIState();
|
this.#updateUIState();
|
||||||
|
|
||||||
this.#currentEditor = editor;
|
this.#currentEditor = editor;
|
||||||
@ -157,7 +183,23 @@ class AltTextManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#cancel() {
|
||||||
|
this.#eventBus.dispatch("reporttelemetry", {
|
||||||
|
source: this,
|
||||||
|
details: {
|
||||||
|
type: "editing",
|
||||||
|
subtype: this.#currentEditor.editorType,
|
||||||
|
data: {
|
||||||
|
action: "alt_text_cancel",
|
||||||
|
alt_text_keyboard: !this.#hasUsedPointer,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.#finish();
|
||||||
|
}
|
||||||
|
|
||||||
#close() {
|
#close() {
|
||||||
|
this.#removePointerDownListeners();
|
||||||
this.#uiManager?.addEditListeners();
|
this.#uiManager?.addEditListeners();
|
||||||
this.#eventBus._off("resize", this.#boundSetPosition);
|
this.#eventBus._off("resize", this.#boundSetPosition);
|
||||||
this.#currentEditor = null;
|
this.#currentEditor = null;
|
||||||
@ -173,13 +215,41 @@ class AltTextManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#save() {
|
#save() {
|
||||||
|
const altText = this.#textarea.value.trim();
|
||||||
|
const decorative = this.#optionDecorative.checked;
|
||||||
this.#currentEditor.altTextData = {
|
this.#currentEditor.altTextData = {
|
||||||
altText: this.#textarea.value.trim(),
|
altText,
|
||||||
decorative: this.#optionDecorative.checked,
|
decorative,
|
||||||
};
|
};
|
||||||
|
this.#eventBus.dispatch("reporttelemetry", {
|
||||||
|
source: this,
|
||||||
|
details: {
|
||||||
|
type: "editing",
|
||||||
|
subtype: this.#currentEditor.editorType,
|
||||||
|
data: {
|
||||||
|
action: "alt_text_save",
|
||||||
|
alt_text_description: !!altText,
|
||||||
|
alt_text_edit:
|
||||||
|
this.#previousAltText && this.#previousAltText !== altText,
|
||||||
|
alt_text_decorative: decorative,
|
||||||
|
alt_text_keyboard: !this.#hasUsedPointer,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
this.#finish();
|
this.#finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pointerDown() {
|
||||||
|
this.#hasUsedPointer = true;
|
||||||
|
this.#removePointerDownListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
#removePointerDownListeners() {
|
||||||
|
for (const element of this._elements) {
|
||||||
|
element.removeEventListener("pointerdown", this.#boundPointerDown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
this.#currentEditor = null;
|
this.#currentEditor = null;
|
||||||
this.#uiManager = null;
|
this.#uiManager = null;
|
||||||
|
@ -2012,6 +2012,7 @@ const PDFViewerApplication = {
|
|||||||
"annotationeditorstateschanged",
|
"annotationeditorstateschanged",
|
||||||
webViewerAnnotationEditorStatesChanged
|
webViewerAnnotationEditorStatesChanged
|
||||||
);
|
);
|
||||||
|
eventBus._on("reporttelemetry", webViewerReportTelemetry);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -2141,6 +2142,10 @@ const PDFViewerApplication = {
|
|||||||
eventBus._off("openfile", webViewerOpenFile);
|
eventBus._off("openfile", webViewerOpenFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
|
||||||
|
eventBus._off("reporttelemetry", webViewerReportTelemetry);
|
||||||
|
}
|
||||||
|
|
||||||
_boundEvents.beforePrint = null;
|
_boundEvents.beforePrint = null;
|
||||||
_boundEvents.afterPrint = null;
|
_boundEvents.afterPrint = null;
|
||||||
},
|
},
|
||||||
@ -3289,6 +3294,10 @@ function webViewerAnnotationEditorStatesChanged(data) {
|
|||||||
PDFViewerApplication.externalServices.updateEditorStates(data);
|
PDFViewerApplication.externalServices.updateEditorStates(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function webViewerReportTelemetry({ details }) {
|
||||||
|
PDFViewerApplication.externalServices.reportTelemetry(details);
|
||||||
|
}
|
||||||
|
|
||||||
/* Abstract factory for the print service. */
|
/* Abstract factory for the print service. */
|
||||||
const PDFPrintServiceFactory = {
|
const PDFPrintServiceFactory = {
|
||||||
instance: {
|
instance: {
|
||||||
|
Loading…
Reference in New Issue
Block a user