[Editor] Add the possibility to paste an image from the clipboard (bug 1848317)
This commit is contained in:
parent
4b2eebf32e
commit
2dd6f07b57
@ -464,6 +464,31 @@ class AnnotationEditorLayer {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paste some content into a new editor.
|
||||||
|
* @param {number} mode
|
||||||
|
* @param {Object} params
|
||||||
|
*/
|
||||||
|
pasteEditor(mode, params) {
|
||||||
|
this.#uiManager.updateToolbar(mode);
|
||||||
|
this.#uiManager.updateMode(mode);
|
||||||
|
|
||||||
|
const { offsetX, offsetY } = this.#getCenterPoint();
|
||||||
|
const id = this.getNextId();
|
||||||
|
const editor = this.#createNewEditor({
|
||||||
|
parent: this,
|
||||||
|
id,
|
||||||
|
x: offsetX,
|
||||||
|
y: offsetY,
|
||||||
|
uiManager: this.#uiManager,
|
||||||
|
isCentered: true,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
if (editor) {
|
||||||
|
this.add(editor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new editor
|
* Create a new editor
|
||||||
* @param {Object} data
|
* @param {Object} data
|
||||||
@ -504,10 +529,7 @@ class AnnotationEditorLayer {
|
|||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#getCenterPoint() {
|
||||||
* Create and add a new editor.
|
|
||||||
*/
|
|
||||||
addNewEditor() {
|
|
||||||
const { x, y, width, height } = this.div.getBoundingClientRect();
|
const { x, y, width, height } = this.div.getBoundingClientRect();
|
||||||
const tlX = Math.max(0, x);
|
const tlX = Math.max(0, x);
|
||||||
const tlY = Math.max(0, y);
|
const tlY = Math.max(0, y);
|
||||||
@ -520,11 +542,15 @@ class AnnotationEditorLayer {
|
|||||||
? [centerX, centerY]
|
? [centerX, centerY]
|
||||||
: [centerY, centerX];
|
: [centerY, centerX];
|
||||||
|
|
||||||
|
return { offsetX, offsetY };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and add a new editor.
|
||||||
|
*/
|
||||||
|
addNewEditor() {
|
||||||
this.#createAndAddNewEditor(
|
this.#createAndAddNewEditor(
|
||||||
{
|
this.#getCenterPoint(),
|
||||||
offsetX,
|
|
||||||
offsetY,
|
|
||||||
},
|
|
||||||
/* isCentered = */ true
|
/* isCentered = */ true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -140,6 +140,26 @@ class AnnotationEditor {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this kind of editor is able to handle the given mime type for
|
||||||
|
* pasting.
|
||||||
|
* @param {string} mime
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
static isHandlingMimeForPasting(_mime) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the data from the clipboard item and delegate the creation of the
|
||||||
|
* editor to the parent.
|
||||||
|
* @param {DataTransferItem} item
|
||||||
|
* @param {AnnotationEditorLayer} parent
|
||||||
|
*/
|
||||||
|
static paste(item, parent) {
|
||||||
|
unreachable("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the properties to update in the UI for this editor.
|
* Get the properties to update in the UI for this editor.
|
||||||
* @returns {Array}
|
* @returns {Array}
|
||||||
|
@ -30,6 +30,8 @@ class StampEditor extends AnnotationEditor {
|
|||||||
|
|
||||||
#bitmapUrl = null;
|
#bitmapUrl = null;
|
||||||
|
|
||||||
|
#bitmapFile = null;
|
||||||
|
|
||||||
#canvas = null;
|
#canvas = null;
|
||||||
|
|
||||||
#observer = null;
|
#observer = null;
|
||||||
@ -45,6 +47,7 @@ class StampEditor extends AnnotationEditor {
|
|||||||
constructor(params) {
|
constructor(params) {
|
||||||
super({ ...params, name: "stampEditor" });
|
super({ ...params, name: "stampEditor" });
|
||||||
this.#bitmapUrl = params.bitmapUrl;
|
this.#bitmapUrl = params.bitmapUrl;
|
||||||
|
this.#bitmapFile = params.bitmapFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get supportedTypes() {
|
static get supportedTypes() {
|
||||||
@ -64,10 +67,26 @@ class StampEditor extends AnnotationEditor {
|
|||||||
return shadow(
|
return shadow(
|
||||||
this,
|
this,
|
||||||
"supportedTypes",
|
"supportedTypes",
|
||||||
types.map(type => `image/${type}`).join(",")
|
types.map(type => `image/${type}`)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get supportedTypesStr() {
|
||||||
|
return shadow(this, "supportedTypesStr", this.supportedTypes.join(","));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritdoc */
|
||||||
|
static isHandlingMimeForPasting(mime) {
|
||||||
|
return this.supportedTypes.includes(mime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritdoc */
|
||||||
|
static paste(item, parent) {
|
||||||
|
parent.pasteEditor(AnnotationEditorType.STAMP, {
|
||||||
|
bitmapFile: item.getAsFile(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#getBitmapDone() {
|
#getBitmapDone() {
|
||||||
this._uiManager.enableWaiting(false);
|
this._uiManager.enableWaiting(false);
|
||||||
if (this.#canvas) {
|
if (this.#canvas) {
|
||||||
@ -115,6 +134,29 @@ class StampEditor extends AnnotationEditor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.#bitmapFile) {
|
||||||
|
const file = this.#bitmapFile;
|
||||||
|
this.#bitmapFile = null;
|
||||||
|
this._uiManager.enableWaiting(true);
|
||||||
|
this.#bitmapPromise = this._uiManager.imageManager
|
||||||
|
.getFromFile(file)
|
||||||
|
.then(data => {
|
||||||
|
this.#bitmapPromise = null;
|
||||||
|
if (!data) {
|
||||||
|
this.remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
({
|
||||||
|
bitmap: this.#bitmap,
|
||||||
|
id: this.#bitmapId,
|
||||||
|
isSvg: this.#isSvg,
|
||||||
|
} = data);
|
||||||
|
this.#createCanvas();
|
||||||
|
})
|
||||||
|
.finally(() => this.#getBitmapDone());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const input = document.createElement("input");
|
const input = document.createElement("input");
|
||||||
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING")) {
|
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING")) {
|
||||||
input.hidden = true;
|
input.hidden = true;
|
||||||
@ -122,7 +164,7 @@ class StampEditor extends AnnotationEditor {
|
|||||||
document.body.append(input);
|
document.body.append(input);
|
||||||
}
|
}
|
||||||
input.type = "file";
|
input.type = "file";
|
||||||
input.accept = StampEditor.supportedTypes;
|
input.accept = StampEditor.supportedTypesStr;
|
||||||
this.#bitmapPromise = new Promise(resolve => {
|
this.#bitmapPromise = new Promise(resolve => {
|
||||||
input.addEventListener("change", async () => {
|
input.addEventListener("change", async () => {
|
||||||
this.#bitmapPromise = null;
|
this.#bitmapPromise = null;
|
||||||
|
@ -919,8 +919,17 @@ class AnnotationEditorUIManager {
|
|||||||
*/
|
*/
|
||||||
paste(event) {
|
paste(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
const { clipboardData } = event;
|
||||||
|
for (const item of clipboardData.items) {
|
||||||
|
for (const editorType of this.#editorTypes) {
|
||||||
|
if (editorType.isHandlingMimeForPasting(item.type)) {
|
||||||
|
editorType.paste(item, this.currentLayer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let data = event.clipboardData.getData("application/pdfjs");
|
let data = clipboardData.getData("application/pdfjs");
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1099,6 +1108,9 @@ class AnnotationEditorUIManager {
|
|||||||
* @param {string|null} editId
|
* @param {string|null} editId
|
||||||
*/
|
*/
|
||||||
updateMode(mode, editId = null) {
|
updateMode(mode, editId = null) {
|
||||||
|
if (this.#mode === mode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.#mode = mode;
|
this.#mode = mode;
|
||||||
if (mode === AnnotationEditorType.NONE) {
|
if (mode === AnnotationEditorType.NONE) {
|
||||||
this.setEditingState(false);
|
this.setEditingState(false);
|
||||||
|
Loading…
Reference in New Issue
Block a user