@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
120 lines (117 loc) • 4.64 kB
JavaScript
// Disable no-re-export rule for entry point files
/* eslint-disable @atlaskit/editor/no-re-export */
import { AllSelection, NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
import { CellSelection } from '@atlaskit/editor-tables';
import { selectedRect } from '@atlaskit/editor-tables/utils';
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '../analytics';
export { RelativeSelectionPos } from './types';
export { GapCursorSelection, Side, JSON_ID, GapBookmark } from './gap-cursor/selection';
export { setSelectionTopLevelBlocks, setGapCursorAtPos } from './gap-cursor/actions';
export { isIgnored } from './gap-cursor/utils/is-ignored';
export { isValidTargetNode } from './gap-cursor/utils/is-valid-target-node';
export { setGapCursorSelection } from './gap-cursor/utils/setGapCursorSelection';
export { hideCaretModifier, gapCursorStyles } from './gap-cursor/styles';
export { atTheBeginningOfBlock, atTheBeginningOfDoc, atTheEndOfBlock, atTheEndOfDoc, endPositionOfParent, isSelectionAtEndOfNode, isSelectionAtStartOfNode, startPositionOfParent } from './utils';
export function getNodeSelectionAnalyticsPayload(selection) {
if (selection instanceof NodeSelection) {
return {
action: ACTION.SELECTED,
actionSubject: ACTION_SUBJECT.DOCUMENT,
actionSubjectId: ACTION_SUBJECT_ID.NODE,
eventType: EVENT_TYPE.TRACK,
attributes: {
node: selection.node.type.name
}
};
}
}
export function getAllSelectionAnalyticsPayload(selection) {
if (selection instanceof AllSelection) {
return {
action: ACTION.SELECTED,
actionSubject: ACTION_SUBJECT.DOCUMENT,
actionSubjectId: ACTION_SUBJECT_ID.ALL,
eventType: EVENT_TYPE.TRACK
};
}
}
export function getCellSelectionAnalyticsPayload(state) {
if (state.selection instanceof CellSelection) {
var rect = selectedRect(state);
var selectedCells = rect.map.cellsInRect(rect).length;
var totalCells = rect.map.map.length;
return {
action: ACTION.SELECTED,
actionSubject: ACTION_SUBJECT.DOCUMENT,
actionSubjectId: ACTION_SUBJECT_ID.CELL,
eventType: EVENT_TYPE.TRACK,
attributes: {
selectedCells: selectedCells,
totalCells: totalCells
}
};
}
}
export function getRangeSelectionAnalyticsPayload(selection, doc) {
if (selection instanceof TextSelection && selection.from !== selection.to) {
var from = selection.from,
to = selection.to,
anchor = selection.anchor,
head = selection.head;
var nodes = [];
doc.nodesBetween(from, to, function (node, pos) {
// We want to send top-level nodes only, ie.the nodes that would have the selection styling
// We allow text nodes that are not fully covered as they are a special case
if (node.isText || pos >= from && pos + node.nodeSize <= to) {
nodes.push(node.type.name);
return false;
}
});
return {
action: ACTION.SELECTED,
actionSubject: ACTION_SUBJECT.DOCUMENT,
actionSubjectId: ACTION_SUBJECT_ID.RANGE,
eventType: EVENT_TYPE.TRACK,
attributes: {
from: anchor,
to: head,
nodes: nodes
}
};
}
}
/**
* Insert content, delete a range and create a new selection
* This function automatically handles the mapping of positions for insertion and deletion.
* The new selection is handled as a function since it may not always be necessary to resolve a position to the transactions mapping
*
* @param getSelectionResolvedPos get the resolved position to create a new selection
* @param insertions content to insert at the specified position
* @param deletions the ranges to delete
*/
export var selectNode = function selectNode(pos) {
return function (state, dispatch) {
if (dispatch) {
dispatch(state.tr.setSelection(new NodeSelection(state.doc.resolve(pos))));
}
return true;
};
};
export function createSelectionClickHandler(nodes, isValidTarget, options) {
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/max-params
return function handleClickOn(view, pos, node, nodePos, event, direct) {
if (options.useLongPressSelection) {
return false;
}
if (direct && nodes.indexOf(node.type.name) !== -1) {
var target = event.target;
if (target instanceof HTMLElement && isValidTarget(target)) {
var selectionPos = options.getNodeSelectionPos ? options.getNodeSelectionPos(view.state, nodePos) : nodePos;
selectNode(selectionPos)(view.state, view.dispatch);
return true;
}
}
return false;
};
}