@atlaskit/editor-plugin-placeholder
Version:
Placeholder plugin for @atlaskit/editor-core.
241 lines • 11.2 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
import { placeholderTextMessages as messages } from '@atlaskit/editor-common/messages';
import { bracketTyped, hasDocAsParent, isEmptyDocument, isEmptyParagraph } from '@atlaskit/editor-common/utils';
import { findParentNode } from '@atlaskit/editor-prosemirror/utils';
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
import { pluginKey } from '../placeholderPlugin';
import { createLongEmptyNodePlaceholderADF, createShortEmptyNodePlaceholderADF } from './adf-builders';
import { nodeTypesWithLongPlaceholderText, nodeTypesWithShortPlaceholderText, nodeTypesWithSyncBlockPlaceholderText } from './constants';
export function getPlaceholderState(editorState) {
return pluginKey.getState(editorState);
}
export function setPlaceHolderState(_ref) {
var placeholderText = _ref.placeholderText,
pos = _ref.pos,
placeholderPrompts = _ref.placeholderPrompts,
typedAndDeleted = _ref.typedAndDeleted,
userHadTyped = _ref.userHadTyped,
canShowOnEmptyParagraph = _ref.canShowOnEmptyParagraph,
showOnEmptyParagraph = _ref.showOnEmptyParagraph,
contextPlaceholderADF = _ref.contextPlaceholderADF;
return {
hasPlaceholder: true,
placeholderText: placeholderText,
placeholderPrompts: placeholderPrompts,
contextPlaceholderADF: contextPlaceholderADF,
pos: pos ? pos : 1,
typedAndDeleted: typedAndDeleted,
userHadTyped: userHadTyped,
canShowOnEmptyParagraph: canShowOnEmptyParagraph,
showOnEmptyParagraph: showOnEmptyParagraph
};
}
export var emptyPlaceholder = function emptyPlaceholder(_ref2) {
var placeholderText = _ref2.placeholderText,
placeholderPrompts = _ref2.placeholderPrompts,
userHadTyped = _ref2.userHadTyped,
pos = _ref2.pos,
canShowOnEmptyParagraph = _ref2.canShowOnEmptyParagraph,
showOnEmptyParagraph = _ref2.showOnEmptyParagraph;
return {
hasPlaceholder: false,
placeholderText: placeholderText,
placeholderPrompts: placeholderPrompts,
userHadTyped: userHadTyped,
typedAndDeleted: false,
canShowOnEmptyParagraph: canShowOnEmptyParagraph,
showOnEmptyParagraph: showOnEmptyParagraph,
pos: pos
};
};
export function createPlaceHolderStateFrom(_ref3) {
var isInitial = _ref3.isInitial,
isEditorFocused = _ref3.isEditorFocused,
editorState = _ref3.editorState,
isTypeAheadOpen = _ref3.isTypeAheadOpen,
defaultPlaceholderText = _ref3.defaultPlaceholderText,
intl = _ref3.intl,
bracketPlaceholderText = _ref3.bracketPlaceholderText,
emptyLinePlaceholder = _ref3.emptyLinePlaceholder,
placeholderADF = _ref3.placeholderADF,
placeholderPrompts = _ref3.placeholderPrompts,
typedAndDeleted = _ref3.typedAndDeleted,
userHadTyped = _ref3.userHadTyped,
isPlaceholderHidden = _ref3.isPlaceholderHidden,
withEmptyParagraph = _ref3.withEmptyParagraph,
showOnEmptyParagraph = _ref3.showOnEmptyParagraph;
var shouldHidePlaceholder = isPlaceholderHidden;
if (shouldHidePlaceholder) {
return _objectSpread(_objectSpread({}, emptyPlaceholder({
placeholderText: defaultPlaceholderText,
placeholderPrompts: placeholderPrompts,
userHadTyped: userHadTyped
})), {}, {
isPlaceholderHidden: isPlaceholderHidden
});
}
if (isTypeAheadOpen !== null && isTypeAheadOpen !== void 0 && isTypeAheadOpen(editorState)) {
return emptyPlaceholder({
placeholderText: defaultPlaceholderText,
placeholderPrompts: placeholderPrompts,
userHadTyped: userHadTyped
});
}
if ((defaultPlaceholderText || placeholderPrompts || placeholderADF) && isEmptyDocument(editorState.doc)) {
return setPlaceHolderState({
placeholderText: defaultPlaceholderText,
pos: 1,
placeholderPrompts: placeholderPrompts,
typedAndDeleted: typedAndDeleted,
userHadTyped: userHadTyped
});
}
if (withEmptyParagraph) {
var _editorState$selectio = editorState.selection,
from = _editorState$selectio.from,
to = _editorState$selectio.to,
$to = _editorState$selectio.$to;
var isOnEmptyParagraphInNonEmptyDoc = (defaultPlaceholderText || placeholderADF) && withEmptyParagraph && !isInitial && !isEmptyDocument(editorState.doc) && from === to && isEmptyParagraph($to.parent) && hasDocAsParent($to);
if (isOnEmptyParagraphInNonEmptyDoc) {
// If placeholder was already shown, keep it visible even without focus
// This prevents the placeholder from disappearing when switching browser tabs
if (showOnEmptyParagraph) {
return setPlaceHolderState({
placeholderText: defaultPlaceholderText,
pos: to,
placeholderPrompts: placeholderPrompts,
typedAndDeleted: typedAndDeleted,
userHadTyped: userHadTyped,
canShowOnEmptyParagraph: true,
showOnEmptyParagraph: true
});
}
// Focus is required to start the timeout for showing placeholder
if (isEditorFocused) {
return emptyPlaceholder({
placeholderText: defaultPlaceholderText,
placeholderPrompts: placeholderPrompts,
userHadTyped: userHadTyped,
canShowOnEmptyParagraph: true,
showOnEmptyParagraph: false,
pos: to
});
}
}
}
if (isEditorFocused && editorExperiment('platform_editor_controls', 'variant1')) {
var _parentNode$firstChil, _parentNode$firstChil2;
var _editorState$selectio2 = editorState.selection,
$from = _editorState$selectio2.$from,
_$to = _editorState$selectio2.$to;
if ($from.pos !== _$to.pos) {
return emptyPlaceholder({
placeholderText: defaultPlaceholderText,
placeholderPrompts: placeholderPrompts,
userHadTyped: userHadTyped
});
}
var parentNode = $from.node($from.depth - 1);
var parentType = parentNode === null || parentNode === void 0 ? void 0 : parentNode.type.name;
if (emptyLinePlaceholder && parentType === 'doc') {
var isEmptyLine = isEmptyParagraph($from.parent);
if (isEmptyLine) {
return setPlaceHolderState({
placeholderText: emptyLinePlaceholder,
pos: $from.pos,
placeholderPrompts: placeholderPrompts,
typedAndDeleted: typedAndDeleted,
userHadTyped: userHadTyped
});
}
}
var isEmptyNode = (parentNode === null || parentNode === void 0 ? void 0 : parentNode.childCount) === 1 && ((_parentNode$firstChil = parentNode.firstChild) === null || _parentNode$firstChil === void 0 ? void 0 : _parentNode$firstChil.content.size) === 0 && ((_parentNode$firstChil2 = parentNode.firstChild) === null || _parentNode$firstChil2 === void 0 ? void 0 : _parentNode$firstChil2.type.name) === 'paragraph';
if (nodeTypesWithShortPlaceholderText.includes(parentType) && isEmptyNode) {
var _table$node$firstChil;
var table = findParentNode(function (node) {
return node.type === editorState.schema.nodes.table;
})(editorState.selection);
if (!table) {
return emptyPlaceholder({
placeholderText: defaultPlaceholderText,
placeholderPrompts: placeholderPrompts,
userHadTyped: userHadTyped
});
}
var isFirstCell = (table === null || table === void 0 || (_table$node$firstChil = table.node.firstChild) === null || _table$node$firstChil === void 0 ? void 0 : _table$node$firstChil.content.firstChild) === parentNode;
if (isFirstCell) {
return setPlaceHolderState({
placeholderText: undefined,
contextPlaceholderADF: createShortEmptyNodePlaceholderADF(intl),
pos: $from.pos,
placeholderPrompts: placeholderPrompts,
typedAndDeleted: typedAndDeleted,
userHadTyped: userHadTyped
});
}
}
if (nodeTypesWithLongPlaceholderText.includes(parentType) && isEmptyNode) {
return setPlaceHolderState({
placeholderText: undefined,
contextPlaceholderADF: createLongEmptyNodePlaceholderADF(intl),
pos: $from.pos,
placeholderPrompts: placeholderPrompts,
typedAndDeleted: typedAndDeleted,
userHadTyped: userHadTyped
});
}
if (nodeTypesWithSyncBlockPlaceholderText.includes(parentType) && isEmptyNode && editorExperiment('platform_synced_block', true)) {
return setPlaceHolderState({
placeholderText: intl.formatMessage(messages.sourceSyncBlockPlaceholderText),
pos: $from.pos,
placeholderPrompts: placeholderPrompts,
typedAndDeleted: typedAndDeleted,
userHadTyped: userHadTyped
});
}
return emptyPlaceholder({
placeholderText: defaultPlaceholderText,
placeholderPrompts: placeholderPrompts,
userHadTyped: userHadTyped
});
}
if (bracketPlaceholderText && bracketTyped(editorState) && isEditorFocused) {
var _$from = editorState.selection.$from;
// Space is to account for positioning of the bracket
var bracketHint = ' ' + bracketPlaceholderText;
return setPlaceHolderState({
placeholderText: bracketHint,
pos: _$from.pos - 1,
placeholderPrompts: placeholderPrompts,
typedAndDeleted: typedAndDeleted,
userHadTyped: userHadTyped
});
}
return emptyPlaceholder({
placeholderText: defaultPlaceholderText,
placeholderPrompts: placeholderPrompts,
userHadTyped: userHadTyped
});
}
export function calculateUserInteractionState(_ref4) {
var placeholderState = _ref4.placeholderState,
oldEditorState = _ref4.oldEditorState,
newEditorState = _ref4.newEditorState;
var wasEmpty = oldEditorState ? isEmptyDocument(oldEditorState.doc) : true;
var isEmpty = isEmptyDocument(newEditorState.doc);
var hasEverTyped = Boolean(placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.userHadTyped) ||
// Previously typed
!wasEmpty ||
// Had content before
wasEmpty && !isEmpty; // Just added content
var justDeletedAll = hasEverTyped && isEmpty && !wasEmpty;
var isInTypedAndDeletedState = justDeletedAll || Boolean(placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.typedAndDeleted) && isEmpty;
// Only reset user interaction tracking when editor is cleanly empty
var shouldResetInteraction = isEmpty && !isInTypedAndDeletedState;
return {
userHadTyped: shouldResetInteraction ? false : hasEverTyped,
typedAndDeleted: isInTypedAndDeletedState
};
}