"use strict"; exports.__esModule = true; exports.setResponderId = setResponderId; exports.getResponderPaths = getResponderPaths; exports.getLowestCommonAncestor = getLowestCommonAncestor; exports.hasTargetTouches = hasTargetTouches; exports.hasValidSelection = hasValidSelection; exports.isPrimaryPointerDown = isPrimaryPointerDown; var _isSelectionValid = _interopRequireDefault(require("../../modules/isSelectionValid")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Copyright (c) Nicolas Gallagher * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ var keyName = '__reactResponderId'; function getEventPath(domEvent) { // The 'selectionchange' event always has the 'document' as the target. // Use the anchor node as the initial target to reconstruct a path. // (We actually only need the first "responder" node in practice.) if (domEvent.type === 'selectionchange') { var target = window.getSelection().anchorNode; return composedPathFallback(target); } else { var path = domEvent.composedPath != null ? domEvent.composedPath() : composedPathFallback(domEvent.target); return path; } } function composedPathFallback(target) { var path = []; while (target != null && target !== document.body) { path.push(target); target = target.parentNode; } return path; } /** * Retrieve the responderId from a host node */ function getResponderId(node) { if (node != null) { return node[keyName]; } return null; } /** * Store the responderId on a host node */ function setResponderId(node, id) { if (node != null) { node[keyName] = id; } } /** * Filter the event path to contain only the nodes attached to the responder system */ function getResponderPaths(domEvent) { var idPath = []; var nodePath = []; var eventPath = getEventPath(domEvent); for (var i = 0; i < eventPath.length; i++) { var node = eventPath[i]; var id = getResponderId(node); if (id != null) { idPath.push(id); nodePath.push(node); } } return { idPath: idPath, nodePath: nodePath }; } /** * Walk the paths and find the first common ancestor */ function getLowestCommonAncestor(pathA, pathB) { var pathALength = pathA.length; var pathBLength = pathB.length; if ( // If either path is empty pathALength === 0 || pathBLength === 0 || // If the last elements aren't the same there can't be a common ancestor // that is connected to the responder system pathA[pathALength - 1] !== pathB[pathBLength - 1]) { return null; } var itemA = pathA[0]; var indexA = 0; var itemB = pathB[0]; var indexB = 0; // If A is deeper, skip indices that can't match. if (pathALength - pathBLength > 0) { indexA = pathALength - pathBLength; itemA = pathA[indexA]; pathALength = pathBLength; } // If B is deeper, skip indices that can't match if (pathBLength - pathALength > 0) { indexB = pathBLength - pathALength; itemB = pathB[indexB]; pathBLength = pathALength; } // Walk in lockstep until a match is found var depth = pathALength; while (depth--) { if (itemA === itemB) { return itemA; } itemA = pathA[indexA++]; itemB = pathB[indexB++]; } return null; } /** * Determine whether any of the active touches are within the current responder. * This cannot rely on W3C `targetTouches`, as neither IE11 nor Safari implement it. */ function hasTargetTouches(target, touches) { if (!touches || touches.length === 0) { return false; } for (var i = 0; i < touches.length; i++) { var node = touches[i].target; if (node != null) { if (target.contains(node)) { return true; } } } return false; } /** * Ignore 'selectionchange' events that don't correspond with a person's intent to * select text. */ function hasValidSelection(domEvent) { if (domEvent.type === 'selectionchange') { return (0, _isSelectionValid.default)(); } return domEvent.type === 'select'; } /** * Events are only valid if the primary button was used without specific modifier keys. */ function isPrimaryPointerDown(domEvent) { var altKey = domEvent.altKey, button = domEvent.button, buttons = domEvent.buttons, ctrlKey = domEvent.ctrlKey, type = domEvent.type; var isTouch = type === 'touchstart' || type === 'touchmove'; var isPrimaryMouseDown = type === 'mousedown' && (button === 0 || buttons === 1); var isPrimaryMouseMove = type === 'mousemove' && buttons === 1; var noModifiers = altKey === false && ctrlKey === false; if (isTouch || isPrimaryMouseDown && noModifiers || isPrimaryMouseMove && noModifiers) { return true; } return false; }