@atlaskit/editor-plugin-analytics
Version:
Analytics plugin for @atlaskit/editor-core
98 lines (97 loc) • 3.9 kB
JavaScript
import { ACTION, ACTION_SUBJECT, SELECTION_POSITION, SELECTION_TYPE } from '@atlaskit/editor-common/analytics';
import { findInsertLocation } from '@atlaskit/editor-common/utils/analytics';
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
import { findParentNode, findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
export function getSelectionType(selection) {
var _selection$constructo;
let type;
let position;
if ((selection === null || selection === void 0 ? void 0 : (_selection$constructo = selection.constructor) === null || _selection$constructo === void 0 ? void 0 : _selection$constructo.name) === 'GapCursorSelection') {
type = SELECTION_TYPE.GAP_CURSOR;
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
position = selection.side;
} else if (selection instanceof CellSelection) {
type = SELECTION_TYPE.CELL;
} else if (selection instanceof NodeSelection) {
type = SELECTION_TYPE.NODE;
} else if (selection.from !== selection.to) {
type = SELECTION_TYPE.RANGED;
} else {
type = SELECTION_TYPE.CURSOR;
const {
from,
$from
} = selection;
if (from === $from.start()) {
position = SELECTION_POSITION.START;
} else if (from === $from.end()) {
position = SELECTION_POSITION.END;
} else {
position = SELECTION_POSITION.MIDDLE;
}
}
return {
type,
position
};
}
function findInsertedLocation(oldSelection, newSelection, tr) {
const {
schema
} = newSelection.$from.doc.type;
const {
nodes: {
paragraph,
table
}
} = schema;
if (oldSelection instanceof CellSelection) {
return table.name;
}
const newDoc = newSelection.$from.doc;
const insertLocationInfo = findParentNode(node => node.type !== paragraph)(oldSelection);
let pos = (insertLocationInfo === null || insertLocationInfo === void 0 ? void 0 : insertLocationInfo.start) || 0;
if (expValEquals('platform_editor_insert_location_check', 'isEnabled', true)) {
// Map the old document position through the transaction's steps
pos = tr.mapping.map(pos);
}
let parentNodePos = newDoc.resolve(pos);
// Keep going one level above the attempted insert position till we find a node that contains the current cursor position in it's range
while (parentNodePos.end() < newSelection.$from.pos) {
parentNodePos = newDoc.resolve(parentNodePos.start(Math.max(parentNodePos.depth - 1, 0)));
}
return parentNodePos.node().type.name;
}
export function getStateContext(selection, payload, tr) {
if (!payload.attributes) {
return payload;
}
const {
type,
position
} = getSelectionType(selection);
payload.attributes.selectionType = type;
if (position) {
payload.attributes.selectionPosition = position;
}
const insertLocation = findInsertLocation(selection);
if (tr && payload.action === ACTION.INSERTED && payload.actionSubject !== ACTION_SUBJECT.ANNOTATION && payload.actionSubject !== ACTION_SUBJECT.EDITOR_PLUGIN_AI) {
payload.attributes.insertedLocation = findInsertedLocation(selection, tr.selection, tr);
}
if (payload.action === ACTION.INSERTED && payload.actionSubject === ACTION_SUBJECT.DOCUMENT && payload.attributes) {
payload.attributes.insertLocation = insertLocation;
if (editorExperiment('platform_synced_block', true)) {
const {
bodiedSyncBlock
} = selection.$from.doc.type.schema.nodes;
payload.attributes.isInsideSyncedBlock = Boolean(findParentNodeOfType(bodiedSyncBlock)(selection));
}
} else {
payload.attributes.nodeLocation = insertLocation;
}
return payload;
}