@atlaskit/editor-plugin-paste-options-toolbar
Version:
Paste options toolbar for @atlaskit/editor-core
84 lines (80 loc) • 3.14 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.firePasteActionsMenuExperimentExposure = void 0;
var _expVal = require("@atlaskit/tmp-editor-statsig/expVal");
var hasTableNode = function hasTableNode(slice) {
if (!slice) {
return false;
}
var found = false;
slice.content.descendants(function (node) {
if (node.type.name === 'table') {
found = true;
return false;
}
return true;
});
return found;
};
var isNotProse = function isNotProse(text) {
var trimmed = text.trim();
if (!trimmed) {
return false;
}
// Check each character: if we find whitespace it's prose-like,
// if we find a non-ASCII character it's likely CJK/Thai/etc.
for (var i = 0; i < trimmed.length; i++) {
var code = trimmed.charCodeAt(i);
// Whitespace (space, tab, newline, etc.) → prose-like
if (code === 0x20 || code === 0x09 || code === 0x0a || code === 0x0d) {
return false;
}
// Non-ASCII character → likely a non-Latin script (CJK, Thai, etc.)
if (code > 0x7f) {
return false;
}
}
// No whitespace and all ASCII → URL, token, path, etc.
return true;
};
// Remove this file when experiment `platform_editor_paste_actions_menu` is cleaned up.
// Manual exposure event for `platform_editor_paste_actions_menu`. Due to the fact that as part of this experiment
// the paste menu was completely redesigned, it was very difficult to ensure that an exposure event fires accurately
// for both control and test cohorts without executing code paths for both menus.
// This manual exposure event executes all criteria for showing AI buttons and fires the exposure manually in a code path that
// is guaranteed to execute on both control and test.
var firePasteActionsMenuExperimentExposure = exports.firePasteActionsMenuExperimentExposure = function firePasteActionsMenuExperimentExposure(contentLength, state, pasteStartPos, pasteEndPos, pastedText, pastedSlice) {
if (contentLength < 100 || !pasteStartPos || !pasteEndPos || !pastedText) {
return;
}
if (isNotProse(pastedText)) {
return;
}
if (hasTableNode(pastedSlice)) {
return;
}
try {
var $pos = state.doc.resolve(pasteStartPos);
var pasteAncestorNodeNames = [];
for (var depth = $pos.depth; depth > 0; depth--) {
// Only include an ancestor if the entire pasted range is contained within it.
// This prevents nodes like 'heading' from being flagged as ancestors when the
// pasted content starts in a heading but extends beyond it (e.g. heading + paragraph).
if (pasteEndPos <= $pos.end(depth)) {
pasteAncestorNodeNames.push($pos.node(depth).type.name);
}
}
var isInExcludedNode = pasteAncestorNodeNames.some(function (name) {
return ['codeBlock', 'heading'].includes(name);
});
if (!isInExcludedNode) {
(0, _expVal.expVal)('platform_editor_paste_actions_menu', 'isEnabled', false);
}
} catch (_unused) {
// pasteStartPos may be out of bounds if the document changed between
// when the paste was recorded and when this effect fires.
return;
}
};