123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- /**
- * @licstart The following is the entire license notice for the
- * JavaScript code in this page
- *
- * Copyright 2022 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.
- *
- * @licend The above is the entire license notice for the
- * JavaScript code in this page
- */
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.FreeTextEditor = void 0;
- var _util = require("../../shared/util.js");
- var _tools = require("./tools.js");
- var _editor = require("./editor.js");
- class FreeTextEditor extends _editor.AnnotationEditor {
- #boundEditorDivBlur = this.editorDivBlur.bind(this);
- #boundEditorDivFocus = this.editorDivFocus.bind(this);
- #boundEditorDivInput = this.editorDivInput.bind(this);
- #boundEditorDivKeydown = this.editorDivKeydown.bind(this);
- #color;
- #content = "";
- #editorDivId = `${this.id}-editor`;
- #hasAlreadyBeenCommitted = false;
- #fontSize;
- static _freeTextDefaultContent = "";
- static _l10nPromise;
- static _internalPadding = 0;
- static _defaultColor = null;
- static _defaultFontSize = 10;
- static _keyboardManager = new _tools.KeyboardManager([[["ctrl+Enter", "mac+meta+Enter", "Escape", "mac+Escape"], FreeTextEditor.prototype.commitOrRemove]]);
- static _type = "freetext";
- constructor(params) {
- super({
- ...params,
- name: "freeTextEditor"
- });
- this.#color = params.color || FreeTextEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor;
- this.#fontSize = params.fontSize || FreeTextEditor._defaultFontSize;
- }
- static initialize(l10n) {
- this._l10nPromise = new Map(["free_text2_default_content", "editor_free_text2_aria_label"].map(str => [str, l10n.get(str)]));
- const style = getComputedStyle(document.documentElement);
- this._internalPadding = parseFloat(style.getPropertyValue("--freetext-padding"));
- }
- static updateDefaultParams(type, value) {
- switch (type) {
- case _util.AnnotationEditorParamsType.FREETEXT_SIZE:
- FreeTextEditor._defaultFontSize = value;
- break;
- case _util.AnnotationEditorParamsType.FREETEXT_COLOR:
- FreeTextEditor._defaultColor = value;
- break;
- }
- }
- updateParams(type, value) {
- switch (type) {
- case _util.AnnotationEditorParamsType.FREETEXT_SIZE:
- this.#updateFontSize(value);
- break;
- case _util.AnnotationEditorParamsType.FREETEXT_COLOR:
- this.#updateColor(value);
- break;
- }
- }
- static get defaultPropertiesToUpdate() {
- return [[_util.AnnotationEditorParamsType.FREETEXT_SIZE, FreeTextEditor._defaultFontSize], [_util.AnnotationEditorParamsType.FREETEXT_COLOR, FreeTextEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor]];
- }
- get propertiesToUpdate() {
- return [[_util.AnnotationEditorParamsType.FREETEXT_SIZE, this.#fontSize], [_util.AnnotationEditorParamsType.FREETEXT_COLOR, this.#color]];
- }
- #updateFontSize(fontSize) {
- const setFontsize = size => {
- this.editorDiv.style.fontSize = `calc(${size}px * var(--scale-factor))`;
- this.translate(0, -(size - this.#fontSize) * this.parentScale);
- this.#fontSize = size;
- this.#setEditorDimensions();
- };
- const savedFontsize = this.#fontSize;
- this.addCommands({
- cmd: () => {
- setFontsize(fontSize);
- },
- undo: () => {
- setFontsize(savedFontsize);
- },
- mustExec: true,
- type: _util.AnnotationEditorParamsType.FREETEXT_SIZE,
- overwriteIfSameType: true,
- keepUndo: true
- });
- }
- #updateColor(color) {
- const savedColor = this.#color;
- this.addCommands({
- cmd: () => {
- this.#color = this.editorDiv.style.color = color;
- },
- undo: () => {
- this.#color = this.editorDiv.style.color = savedColor;
- },
- mustExec: true,
- type: _util.AnnotationEditorParamsType.FREETEXT_COLOR,
- overwriteIfSameType: true,
- keepUndo: true
- });
- }
- getInitialTranslation() {
- const scale = this.parentScale;
- return [-FreeTextEditor._internalPadding * scale, -(FreeTextEditor._internalPadding + this.#fontSize) * scale];
- }
- rebuild() {
- super.rebuild();
- if (this.div === null) {
- return;
- }
- if (!this.isAttachedToDOM) {
- this.parent.add(this);
- }
- }
- enableEditMode() {
- if (this.isInEditMode()) {
- return;
- }
- this.parent.setEditingState(false);
- this.parent.updateToolbar(_util.AnnotationEditorType.FREETEXT);
- super.enableEditMode();
- this.overlayDiv.classList.remove("enabled");
- this.editorDiv.contentEditable = true;
- this.div.draggable = false;
- this.div.removeAttribute("aria-activedescendant");
- this.editorDiv.addEventListener("keydown", this.#boundEditorDivKeydown);
- this.editorDiv.addEventListener("focus", this.#boundEditorDivFocus);
- this.editorDiv.addEventListener("blur", this.#boundEditorDivBlur);
- this.editorDiv.addEventListener("input", this.#boundEditorDivInput);
- }
- disableEditMode() {
- if (!this.isInEditMode()) {
- return;
- }
- this.parent.setEditingState(true);
- super.disableEditMode();
- this.overlayDiv.classList.add("enabled");
- this.editorDiv.contentEditable = false;
- this.div.setAttribute("aria-activedescendant", this.#editorDivId);
- this.div.draggable = true;
- this.editorDiv.removeEventListener("keydown", this.#boundEditorDivKeydown);
- this.editorDiv.removeEventListener("focus", this.#boundEditorDivFocus);
- this.editorDiv.removeEventListener("blur", this.#boundEditorDivBlur);
- this.editorDiv.removeEventListener("input", this.#boundEditorDivInput);
- this.div.focus({
- preventScroll: true
- });
- this.isEditing = false;
- this.parent.div.classList.add("freeTextEditing");
- }
- focusin(event) {
- super.focusin(event);
- if (event.target !== this.editorDiv) {
- this.editorDiv.focus();
- }
- }
- onceAdded() {
- if (this.width) {
- return;
- }
- this.enableEditMode();
- this.editorDiv.focus();
- }
- isEmpty() {
- return !this.editorDiv || this.editorDiv.innerText.trim() === "";
- }
- remove() {
- this.isEditing = false;
- this.parent.setEditingState(true);
- this.parent.div.classList.add("freeTextEditing");
- super.remove();
- }
- #extractText() {
- const divs = this.editorDiv.getElementsByTagName("div");
- if (divs.length === 0) {
- return this.editorDiv.innerText;
- }
- const buffer = [];
- for (const div of divs) {
- buffer.push(div.innerText.replace(/\r\n?|\n/, ""));
- }
- return buffer.join("\n");
- }
- #setEditorDimensions() {
- const [parentWidth, parentHeight] = this.parentDimensions;
- let rect;
- if (this.isAttachedToDOM) {
- rect = this.div.getBoundingClientRect();
- } else {
- const {
- currentLayer,
- div
- } = this;
- const savedDisplay = div.style.display;
- div.style.display = "hidden";
- currentLayer.div.append(this.div);
- rect = div.getBoundingClientRect();
- div.remove();
- div.style.display = savedDisplay;
- }
- this.width = rect.width / parentWidth;
- this.height = rect.height / parentHeight;
- }
- commit() {
- if (!this.isInEditMode()) {
- return;
- }
- super.commit();
- if (!this.#hasAlreadyBeenCommitted) {
- this.#hasAlreadyBeenCommitted = true;
- this.parent.addUndoableEditor(this);
- }
- this.disableEditMode();
- this.#content = this.#extractText().trimEnd();
- this.#setEditorDimensions();
- }
- shouldGetKeyboardEvents() {
- return this.isInEditMode();
- }
- dblclick(event) {
- this.enableEditMode();
- this.editorDiv.focus();
- }
- keydown(event) {
- if (event.target === this.div && event.key === "Enter") {
- this.enableEditMode();
- this.editorDiv.focus();
- }
- }
- editorDivKeydown(event) {
- FreeTextEditor._keyboardManager.exec(this, event);
- }
- editorDivFocus(event) {
- this.isEditing = true;
- }
- editorDivBlur(event) {
- this.isEditing = false;
- }
- editorDivInput(event) {
- this.parent.div.classList.toggle("freeTextEditing", this.isEmpty());
- }
- disableEditing() {
- this.editorDiv.setAttribute("role", "comment");
- this.editorDiv.removeAttribute("aria-multiline");
- }
- enableEditing() {
- this.editorDiv.setAttribute("role", "textbox");
- this.editorDiv.setAttribute("aria-multiline", true);
- }
- render() {
- if (this.div) {
- return this.div;
- }
- let baseX, baseY;
- if (this.width) {
- baseX = this.x;
- baseY = this.y;
- }
- super.render();
- this.editorDiv = document.createElement("div");
- this.editorDiv.className = "internal";
- this.editorDiv.setAttribute("id", this.#editorDivId);
- this.enableEditing();
- FreeTextEditor._l10nPromise.get("editor_free_text2_aria_label").then(msg => this.editorDiv?.setAttribute("aria-label", msg));
- FreeTextEditor._l10nPromise.get("free_text2_default_content").then(msg => this.editorDiv?.setAttribute("default-content", msg));
- this.editorDiv.contentEditable = true;
- const {
- style
- } = this.editorDiv;
- style.fontSize = `calc(${this.#fontSize}px * var(--scale-factor))`;
- style.color = this.#color;
- this.div.append(this.editorDiv);
- this.overlayDiv = document.createElement("div");
- this.overlayDiv.classList.add("overlay", "enabled");
- this.div.append(this.overlayDiv);
- (0, _tools.bindEvents)(this, this.div, ["dblclick", "keydown"]);
- if (this.width) {
- const [parentWidth, parentHeight] = this.parentDimensions;
- this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight);
- for (const line of this.#content.split("\n")) {
- const div = document.createElement("div");
- div.append(line ? document.createTextNode(line) : document.createElement("br"));
- this.editorDiv.append(div);
- }
- this.div.draggable = true;
- this.editorDiv.contentEditable = false;
- } else {
- this.div.draggable = false;
- this.editorDiv.contentEditable = true;
- }
- return this.div;
- }
- get contentDiv() {
- return this.editorDiv;
- }
- static deserialize(data, parent, uiManager) {
- const editor = super.deserialize(data, parent, uiManager);
- editor.#fontSize = data.fontSize;
- editor.#color = _util.Util.makeHexColor(...data.color);
- editor.#content = data.value;
- return editor;
- }
- serialize() {
- if (this.isEmpty()) {
- return null;
- }
- const padding = FreeTextEditor._internalPadding * this.parentScale;
- const rect = this.getRect(padding, padding);
- const color = _editor.AnnotationEditor._colorManager.convert(this.isAttachedToDOM ? getComputedStyle(this.editorDiv).color : this.#color);
- return {
- annotationType: _util.AnnotationEditorType.FREETEXT,
- color,
- fontSize: this.#fontSize,
- value: this.#content,
- pageIndex: this.pageIndex,
- rect,
- rotation: this.rotation
- };
- }
- }
- exports.FreeTextEditor = FreeTextEditor;
|