@atlaskit/editor-plugin-placeholder
Version:
Placeholder plugin for @atlaskit/editor-core.
252 lines (251 loc) • 11.7 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.calculateUserInteractionState = calculateUserInteractionState;
exports.createPlaceHolderStateFrom = createPlaceHolderStateFrom;
exports.emptyPlaceholder = void 0;
exports.getPlaceholderState = getPlaceholderState;
exports.setPlaceHolderState = setPlaceHolderState;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _messages = require("@atlaskit/editor-common/messages");
var _utils = require("@atlaskit/editor-common/utils");
var _utils2 = require("@atlaskit/editor-prosemirror/utils");
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
var _placeholderPlugin = require("../placeholderPlugin");
var _adfBuilders = require("./adf-builders");
var _constants = require("./constants");
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) { (0, _defineProperty2.default)(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; }
function getPlaceholderState(editorState) {
return _placeholderPlugin.pluginKey.getState(editorState);
}
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
};
}
var emptyPlaceholder = exports.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
};
};
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) && (0, _utils.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 && !(0, _utils.isEmptyDocument)(editorState.doc) && from === to && (0, _utils.isEmptyParagraph)($to.parent) && (0, _utils.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 && (0, _experiments.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 = (0, _utils.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 (_constants.nodeTypesWithShortPlaceholderText.includes(parentType) && isEmptyNode) {
var _table$node$firstChil;
var table = (0, _utils2.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: (0, _adfBuilders.createShortEmptyNodePlaceholderADF)(intl),
pos: $from.pos,
placeholderPrompts: placeholderPrompts,
typedAndDeleted: typedAndDeleted,
userHadTyped: userHadTyped
});
}
}
if (_constants.nodeTypesWithLongPlaceholderText.includes(parentType) && isEmptyNode) {
return setPlaceHolderState({
placeholderText: undefined,
contextPlaceholderADF: (0, _adfBuilders.createLongEmptyNodePlaceholderADF)(intl),
pos: $from.pos,
placeholderPrompts: placeholderPrompts,
typedAndDeleted: typedAndDeleted,
userHadTyped: userHadTyped
});
}
if (_constants.nodeTypesWithSyncBlockPlaceholderText.includes(parentType) && isEmptyNode && (0, _experiments.editorExperiment)('platform_synced_block', true)) {
return setPlaceHolderState({
placeholderText: intl.formatMessage(_messages.placeholderTextMessages.sourceSyncBlockPlaceholderText),
pos: $from.pos,
placeholderPrompts: placeholderPrompts,
typedAndDeleted: typedAndDeleted,
userHadTyped: userHadTyped
});
}
return emptyPlaceholder({
placeholderText: defaultPlaceholderText,
placeholderPrompts: placeholderPrompts,
userHadTyped: userHadTyped
});
}
if (bracketPlaceholderText && (0, _utils.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
});
}
function calculateUserInteractionState(_ref4) {
var placeholderState = _ref4.placeholderState,
oldEditorState = _ref4.oldEditorState,
newEditorState = _ref4.newEditorState;
var wasEmpty = oldEditorState ? (0, _utils.isEmptyDocument)(oldEditorState.doc) : true;
var isEmpty = (0, _utils.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
};
}