"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.addClassName = addClassName; exports.addEvent = addEvent; exports.addUserSelectStyles = addUserSelectStyles; exports.createCSSTransform = createCSSTransform; exports.createSVGTransform = createSVGTransform; exports.getTouch = getTouch; exports.getTouchIdentifier = getTouchIdentifier; exports.getTranslation = getTranslation; exports.innerHeight = innerHeight; exports.innerWidth = innerWidth; exports.matchesSelector = matchesSelector; exports.matchesSelectorAndParentsTo = matchesSelectorAndParentsTo; exports.offsetXYFromParent = offsetXYFromParent; exports.outerHeight = outerHeight; exports.outerWidth = outerWidth; exports.removeClassName = removeClassName; exports.removeEvent = removeEvent; exports.removeUserSelectStyles = removeUserSelectStyles; var _shims = require("./shims"); var _getPrefix = _interopRequireWildcard(require("./getPrefix")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /*:: import type {ControlPosition, PositionOffsetControlPosition, MouseTouchEvent} from './types';*/ let matchesSelectorFunc = ''; function matchesSelector(el /*: Node*/, selector /*: string*/) /*: boolean*/{ if (!matchesSelectorFunc) { matchesSelectorFunc = (0, _shims.findInArray)(['matches', 'webkitMatchesSelector', 'mozMatchesSelector', 'msMatchesSelector', 'oMatchesSelector'], function (method) { // $FlowIgnore: Doesn't think elements are indexable return (0, _shims.isFunction)(el[method]); }); } // Might not be found entirely (not an Element?) - in that case, bail // $FlowIgnore: Doesn't think elements are indexable if (!(0, _shims.isFunction)(el[matchesSelectorFunc])) return false; // $FlowIgnore: Doesn't think elements are indexable return el[matchesSelectorFunc](selector); } // Works up the tree to the draggable itself attempting to match selector. function matchesSelectorAndParentsTo(el /*: Node*/, selector /*: string*/, baseNode /*: Node*/) /*: boolean*/{ let node = el; do { if (matchesSelector(node, selector)) return true; if (node === baseNode) return false; // $FlowIgnore[incompatible-type] node = node.parentNode; } while (node); return false; } function addEvent(el /*: ?Node*/, event /*: string*/, handler /*: Function*/, inputOptions /*: Object*/) /*: void*/{ if (!el) return; const options = { capture: true, ...inputOptions }; // $FlowIgnore[method-unbinding] if (el.addEventListener) { el.addEventListener(event, handler, options); } else if (el.attachEvent) { el.attachEvent('on' + event, handler); } else { // $FlowIgnore: Doesn't think elements are indexable el['on' + event] = handler; } } function removeEvent(el /*: ?Node*/, event /*: string*/, handler /*: Function*/, inputOptions /*: Object*/) /*: void*/{ if (!el) return; const options = { capture: true, ...inputOptions }; // $FlowIgnore[method-unbinding] if (el.removeEventListener) { el.removeEventListener(event, handler, options); } else if (el.detachEvent) { el.detachEvent('on' + event, handler); } else { // $FlowIgnore: Doesn't think elements are indexable el['on' + event] = null; } } function outerHeight(node /*: HTMLElement*/) /*: number*/{ // This is deliberately excluding margin for our calculations, since we are using // offsetTop which is including margin. See getBoundPosition let height = node.clientHeight; const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); height += (0, _shims.int)(computedStyle.borderTopWidth); height += (0, _shims.int)(computedStyle.borderBottomWidth); return height; } function outerWidth(node /*: HTMLElement*/) /*: number*/{ // This is deliberately excluding margin for our calculations, since we are using // offsetLeft which is including margin. See getBoundPosition let width = node.clientWidth; const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); width += (0, _shims.int)(computedStyle.borderLeftWidth); width += (0, _shims.int)(computedStyle.borderRightWidth); return width; } function innerHeight(node /*: HTMLElement*/) /*: number*/{ let height = node.clientHeight; const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); height -= (0, _shims.int)(computedStyle.paddingTop); height -= (0, _shims.int)(computedStyle.paddingBottom); return height; } function innerWidth(node /*: HTMLElement*/) /*: number*/{ let width = node.clientWidth; const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); width -= (0, _shims.int)(computedStyle.paddingLeft); width -= (0, _shims.int)(computedStyle.paddingRight); return width; } /*:: interface EventWithOffset { clientX: number, clientY: number }*/ // Get from offsetParent function offsetXYFromParent(evt /*: EventWithOffset*/, offsetParent /*: HTMLElement*/, scale /*: number*/) /*: ControlPosition*/{ const isBody = offsetParent === offsetParent.ownerDocument.body; const offsetParentRect = isBody ? { left: 0, top: 0 } : offsetParent.getBoundingClientRect(); const x = (evt.clientX + offsetParent.scrollLeft - offsetParentRect.left) / scale; const y = (evt.clientY + offsetParent.scrollTop - offsetParentRect.top) / scale; return { x, y }; } function createCSSTransform(controlPos /*: ControlPosition*/, positionOffset /*: PositionOffsetControlPosition*/) /*: Object*/{ const translation = getTranslation(controlPos, positionOffset, 'px'); return { [(0, _getPrefix.browserPrefixToKey)('transform', _getPrefix.default)]: translation }; } function createSVGTransform(controlPos /*: ControlPosition*/, positionOffset /*: PositionOffsetControlPosition*/) /*: string*/{ const translation = getTranslation(controlPos, positionOffset, ''); return translation; } function getTranslation(_ref /*:: */, positionOffset /*: PositionOffsetControlPosition*/, unitSuffix /*: string*/) /*: string*/{ let { x, y } /*: ControlPosition*/ = _ref /*: ControlPosition*/; let translation = "translate(".concat(x).concat(unitSuffix, ",").concat(y).concat(unitSuffix, ")"); if (positionOffset) { const defaultX = "".concat(typeof positionOffset.x === 'string' ? positionOffset.x : positionOffset.x + unitSuffix); const defaultY = "".concat(typeof positionOffset.y === 'string' ? positionOffset.y : positionOffset.y + unitSuffix); translation = "translate(".concat(defaultX, ", ").concat(defaultY, ")") + translation; } return translation; } function getTouch(e /*: MouseTouchEvent*/, identifier /*: number*/) /*: ?{clientX: number, clientY: number}*/{ return e.targetTouches && (0, _shims.findInArray)(e.targetTouches, t => identifier === t.identifier) || e.changedTouches && (0, _shims.findInArray)(e.changedTouches, t => identifier === t.identifier); } function getTouchIdentifier(e /*: MouseTouchEvent*/) /*: ?number*/{ if (e.targetTouches && e.targetTouches[0]) return e.targetTouches[0].identifier; if (e.changedTouches && e.changedTouches[0]) return e.changedTouches[0].identifier; } // User-select Hacks: // // Useful for preventing blue highlights all over everything when dragging. // Note we're passing `document` b/c we could be iframed function addUserSelectStyles(doc /*: ?Document*/) { if (!doc) return; let styleEl = doc.getElementById('react-draggable-style-el'); if (!styleEl) { styleEl = doc.createElement('style'); styleEl.type = 'text/css'; styleEl.id = 'react-draggable-style-el'; styleEl.innerHTML = '.react-draggable-transparent-selection *::-moz-selection {all: inherit;}\n'; styleEl.innerHTML += '.react-draggable-transparent-selection *::selection {all: inherit;}\n'; doc.getElementsByTagName('head')[0].appendChild(styleEl); } if (doc.body) addClassName(doc.body, 'react-draggable-transparent-selection'); } function removeUserSelectStyles(doc /*: ?Document*/) { if (!doc) return; try { if (doc.body) removeClassName(doc.body, 'react-draggable-transparent-selection'); // $FlowIgnore: IE if (doc.selection) { // $FlowIgnore: IE doc.selection.empty(); } else { // Remove selection caused by scroll, unless it's a focused input // (we use doc.defaultView in case we're in an iframe) const selection = (doc.defaultView || window).getSelection(); if (selection && selection.type !== 'Caret') { selection.removeAllRanges(); } } } catch (e) { // probably IE } } function addClassName(el /*: HTMLElement*/, className /*: string*/) { if (el.classList) { el.classList.add(className); } else { if (!el.className.match(new RegExp("(?:^|\\s)".concat(className, "(?!\\S)")))) { el.className += " ".concat(className); } } } function removeClassName(el /*: HTMLElement*/, className /*: string*/) { if (el.classList) { el.classList.remove(className); } else { el.className = el.className.replace(new RegExp("(?:^|\\s)".concat(className, "(?!\\S)"), 'g'), ''); } }