UNPKG

@atlaskit/editor-plugin-paste-options-toolbar

Version:

Paste options toolbar for @atlaskit/editor-core

84 lines (80 loc) 3.14 kB
"use strict"; 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; } };