@atlaskit/editor-plugin-paste
Version:
Paste plugin for @atlaskit/editor-core
96 lines (92 loc) • 4.55 kB
JavaScript
import { uuid } from '@atlaskit/adf-schema';
import { mapSlice } from '@atlaskit/editor-common/utils';
import { PastePluginActionTypes } from '../../editor-actions/actions';
import { FLAG_TYPE } from '../../pastePluginType';
import { pluginKey } from '../../pm-plugins/plugin-factory';
var FLAG_ID = /*#__PURE__*/function (FLAG_ID) {
FLAG_ID["CANNOT_PASTE_CONTENT"] = "cannot-paste-content";
return FLAG_ID;
}(FLAG_ID || {});
const transformSyncBlockNode = (node, schema, isFromEditor) => {
// if copying from renderer, flatten out the content and remove the sync block
if (!isFromEditor) {
return node.content;
}
// sync blocks need a unique localId to function correctly
const newAttrs = {
...node.attrs,
localId: uuid.generate()
};
return schema.nodes.syncBlock.create(newAttrs, null, [...node.marks]);
};
const transformBodiedSyncBlockNode = (node, isFromEditor) => {
// if copying from renderer, flatten out the content and remove the bodied sync block
if (!isFromEditor) {
return node.content;
}
// this is not possible as all bodiedSyncBlocks have already been converted into a syncBlock by now.
return node;
};
const showWarningFlag = ({
api,
title,
description,
urlText,
urlHref
}) => {
// Use setTimeout to dispatch transaction in next tick and avoid re-entrant dispatch
setTimeout(() => {
api === null || api === void 0 ? void 0 : api.core.actions.execute(({
tr
}) => {
const flag = {
id: FLAG_ID.CANNOT_PASTE_CONTENT,
description,
title,
urlText,
urlHref,
type: FLAG_TYPE.WARNING
};
return tr.setMeta(pluginKey, {
type: PastePluginActionTypes.SET_ACTIVE_FLAG,
activeFlag: flag
});
});
}, 0);
};
// Check if rawHtml contains a synced block
// example: "<meta charset='utf-8'><html><head></head><body><div data-sync-block=\"\" data-local-id=\"\" data-resource-id=\"d64883c8-1270-431d-a1d3-51d36a1ed5f4\" data-prosemirror-content-type=\"node\" data-prosemirror-node-name=\"syncBlock\" data-prosemirror-node-block=\"true\" data-pm-slice=\"0 0 []\"></div></body></html>"
const hasSyncedBlockInRawHtml = rawHtml => {
return rawHtml.includes('data-sync-block="');
};
/**
* If we are copying from editor, transform the copied source or reference sync block to a new reference sync block
* Otherwise, (e.g. if copying from renderer), flatten out the content and remove the sync block
* Also, show a warning flag if the pasted content contains a synced block and the paste warning options are configured.
*/
export const handleSyncBlocksPaste = (slice, schema, pasteSource, rawHtml, pasteWarningOptions, api) => {
const isFromEditor = pasteSource === 'fabric-editor';
const isSyncedBlockInRawHtml = hasSyncedBlockInRawHtml(rawHtml);
let hasSyncedBlockInSlice = false;
slice = mapSlice(slice, node => {
if (node.type === schema.nodes.syncBlock) {
hasSyncedBlockInSlice = true;
return transformSyncBlockNode(node, schema, isFromEditor);
} else if (node.type === schema.nodes.bodiedSyncBlock) {
hasSyncedBlockInSlice = true;
return transformBodiedSyncBlockNode(node, isFromEditor);
}
return node;
});
if (pasteWarningOptions !== null && pasteWarningOptions !== void 0 && pasteWarningOptions.cannotPasteSyncedBlock && !hasSyncedBlockInSlice && isSyncedBlockInRawHtml) {
var _pasteWarningOptions$, _pasteWarningOptions$2, _pasteWarningOptions$3, _pasteWarningOptions$4;
showWarningFlag({
api,
title: pasteWarningOptions === null || pasteWarningOptions === void 0 ? void 0 : (_pasteWarningOptions$ = pasteWarningOptions.cannotPasteSyncedBlock) === null || _pasteWarningOptions$ === void 0 ? void 0 : _pasteWarningOptions$.title,
description: pasteWarningOptions === null || pasteWarningOptions === void 0 ? void 0 : (_pasteWarningOptions$2 = pasteWarningOptions.cannotPasteSyncedBlock) === null || _pasteWarningOptions$2 === void 0 ? void 0 : _pasteWarningOptions$2.description,
urlText: pasteWarningOptions === null || pasteWarningOptions === void 0 ? void 0 : (_pasteWarningOptions$3 = pasteWarningOptions.cannotPasteSyncedBlock) === null || _pasteWarningOptions$3 === void 0 ? void 0 : _pasteWarningOptions$3.urlText,
urlHref: pasteWarningOptions === null || pasteWarningOptions === void 0 ? void 0 : (_pasteWarningOptions$4 = pasteWarningOptions.cannotPasteSyncedBlock) === null || _pasteWarningOptions$4 === void 0 ? void 0 : _pasteWarningOptions$4.urlHref
});
}
return slice;
};