@atlaskit/editor-plugin-synced-block
Version:
SyncedBlock plugin for @atlaskit/editor-core
107 lines (106 loc) • 5.4 kB
JavaScript
import React from 'react';
import { ACTION_SUBJECT } from '@atlaskit/editor-common/analytics';
import { ErrorBoundary } from '@atlaskit/editor-common/error-boundary';
import ReactNodeView from '@atlaskit/editor-common/react-node-view';
import { SyncBlockSharedCssClassName, SyncBlockActionsProvider } from '@atlaskit/editor-common/sync-block';
import { useFetchSyncBlockData, useFetchSyncBlockTitle } from '@atlaskit/editor-synced-block-provider';
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
import { removeSyncedBlockAtPos } from '../editor-commands';
import { SyncBlockRendererWrapper } from '../ui/SyncBlockRendererWrapper';
export class SyncBlock extends ReactNodeView {
constructor(props) {
super(props.node, props.view, props.getPos, props.portalProviderAPI, props.eventDispatcher, props);
this.options = props.options;
this.api = props.api;
this.syncBlockStore = props.syncBlockStore;
}
createDomRef() {
const domRef = document.createElement('div');
domRef.classList.add(SyncBlockSharedCssClassName.prefix);
return domRef;
}
validUpdate(currentNode, newNode) {
// Only consider as the valid update if the localId and resourceId are the same
// This prevents PM reusing the same node view for different sync block node in live page transition
return currentNode.attrs.localId === newNode.attrs.localId && currentNode.attrs.resourceId === newNode.attrs.resourceId;
}
update(node, decorations, innerDecorations) {
return super.update(node, decorations, innerDecorations, editorExperiment('platform_synced_block_patch_6', true, {
exposure: true
}) ? this.validUpdate : undefined);
}
render({
getPos
}) {
var _this$options, _this$api$syncedBlock, _this$api, _this$api$syncedBlock2, _this$api$syncedBlock3, _this$api2, _this$api2$analytics, _this$options2;
if (!((_this$options = this.options) !== null && _this$options !== void 0 && _this$options.syncedBlockRenderer)) {
return null;
}
const {
resourceId,
localId
} = this.node.attrs;
if (!resourceId || !localId) {
return null;
}
const syncBlockStore = (_this$api$syncedBlock = (_this$api = this.api) === null || _this$api === void 0 ? void 0 : (_this$api$syncedBlock2 = _this$api.syncedBlock) === null || _this$api$syncedBlock2 === void 0 ? void 0 : (_this$api$syncedBlock3 = _this$api$syncedBlock2.sharedState.currentState()) === null || _this$api$syncedBlock3 === void 0 ? void 0 : _this$api$syncedBlock3.syncBlockStore) !== null && _this$api$syncedBlock !== void 0 ? _this$api$syncedBlock : this.syncBlockStore;
if (!syncBlockStore) {
return null;
}
// get document node from data provider
return /*#__PURE__*/React.createElement(ErrorBoundary, {
component: ACTION_SUBJECT.SYNCED_BLOCK,
dispatchAnalyticsEvent: (_this$api2 = this.api) === null || _this$api2 === void 0 ? void 0 : (_this$api2$analytics = _this$api2.analytics) === null || _this$api2$analytics === void 0 ? void 0 : _this$api2$analytics.actions.fireAnalyticsEvent,
fallbackComponent: null
}, /*#__PURE__*/React.createElement(SyncBlockActionsProvider
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
, {
removeSyncBlock: () => {
const pos = getPos();
if (pos !== undefined) {
removeSyncedBlockAtPos(this.api, pos);
}
}
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
fetchSyncBlockSourceInfo: sourceAri => syncBlockStore.referenceManager.fetchSyncBlockSourceInfoBySourceAri(sourceAri)
}, /*#__PURE__*/React.createElement(SyncBlockRendererWrapper, {
localId: this.node.attrs.localId,
syncedBlockRenderer: (_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.syncedBlockRenderer
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
useFetchSyncBlockTitle: () => useFetchSyncBlockTitle(syncBlockStore, this.node)
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
useFetchSyncBlockData: () => {
var _this$api3, _this$api3$analytics, _this$api3$analytics$;
return useFetchSyncBlockData(syncBlockStore, resourceId, localId, (_this$api3 = this.api) === null || _this$api3 === void 0 ? void 0 : (_this$api3$analytics = _this$api3.analytics) === null || _this$api3$analytics === void 0 ? void 0 : (_this$api3$analytics$ = _this$api3$analytics.actions) === null || _this$api3$analytics$ === void 0 ? void 0 : _this$api3$analytics$.fireAnalyticsEvent);
},
api: this.api
})));
}
destroy() {
var _this$unsubscribe;
(_this$unsubscribe = this.unsubscribe) === null || _this$unsubscribe === void 0 ? void 0 : _this$unsubscribe.call(this);
super.destroy();
}
}
export const syncBlockNodeView = ({
options,
pmPluginFactoryParams,
api
}) => (node, view, getPos) => {
const {
portalProviderAPI,
eventDispatcher
} = pmPluginFactoryParams;
return new SyncBlock({
api,
options,
node,
view,
getPos: getPos,
portalProviderAPI,
eventDispatcher
}).init();
};