UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

120 lines (117 loc) 4.64 kB
// 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; }; }