UNPKG

react-draggable

Version:
336 lines (297 loc) 8.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.matchesSelector = matchesSelector; exports.matchesSelectorAndParentsTo = matchesSelectorAndParentsTo; exports.addEvent = addEvent; exports.removeEvent = removeEvent; exports.outerHeight = outerHeight; exports.outerWidth = outerWidth; exports.innerHeight = innerHeight; exports.innerWidth = innerWidth; exports.offsetXYFromParent = offsetXYFromParent; exports.createCSSTransform = createCSSTransform; exports.createSVGTransform = createSVGTransform; exports.getTranslation = getTranslation; exports.getTouch = getTouch; exports.getTouchIdentifier = getTouchIdentifier; exports.addUserSelectStyles = addUserSelectStyles; exports.removeUserSelectStyles = removeUserSelectStyles; exports.styleHacks = styleHacks; exports.addClassName = addClassName; exports.removeClassName = removeClassName; var _shims = require("./shims"); var _getPrefix = _interopRequireWildcard(require("./getPrefix")); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } 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; node = node.parentNode; } while (node); return false; } function addEvent(el /*: ?Node*/ , event /*: string*/ , handler /*: Function*/ ) /*: void*/ { if (!el) { return; } if (el.attachEvent) { el.attachEvent('on' + event, handler); } else if (el.addEventListener) { el.addEventListener(event, handler, true); } else { // $FlowIgnore: Doesn't think elements are indexable el['on' + event] = handler; } } function removeEvent(el /*: ?Node*/ , event /*: string*/ , handler /*: Function*/ ) /*: void*/ { if (!el) { return; } if (el.detachEvent) { el.detachEvent('on' + event, handler); } else if (el.removeEventListener) { el.removeEventListener(event, handler, true); } 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; } // Get from offsetParent function offsetXYFromParent(evt /*: {clientX: number, clientY: number}*/ , offsetParent /*: HTMLElement*/ ) /*: ControlPosition*/ { const isBody = offsetParent === offsetParent.ownerDocument.body; const offsetParentRect = isBody ? { left: 0, top: 0 } : offsetParent.getBoundingClientRect(); const x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left; const y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top; 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({ x, y } /*: ControlPosition*/ , positionOffset /*: PositionOffsetControlPosition*/ , unitSuffix /*: string*/ ) /*: string*/ { let translation = `translate(${x}${unitSuffix},${y}${unitSuffix})`; if (positionOffset) { const defaultX = `${typeof positionOffset.x === 'string' ? positionOffset.x : positionOffset.x + unitSuffix}`; const defaultY = `${typeof positionOffset.y === 'string' ? positionOffset.y : positionOffset.y + unitSuffix}`; translation = `translate(${defaultX}, ${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*/ ) { try { if (doc && doc.body) removeClassName(doc.body, 'react-draggable-transparent-selection'); // $FlowIgnore: IE if (doc.selection) { // $FlowIgnore: IE doc.selection.empty(); } else { window.getSelection().removeAllRanges(); // remove selection caused by scroll } } catch (e) {// probably IE } } function styleHacks(childStyle /*: Object*/ = {}) /*: Object*/ { // Workaround IE pointer events; see #51 // https://github.com/mzabriskie/react-draggable/issues/51#issuecomment-103488278 return { touchAction: 'none', ...childStyle }; } function addClassName(el /*: HTMLElement*/ , className /*: string*/ ) { if (el.classList) { el.classList.add(className); } else { if (!el.className.match(new RegExp(`(?:^|\\s)${className}(?!\\S)`))) { el.className += ` ${className}`; } } } function removeClassName(el /*: HTMLElement*/ , className /*: string*/ ) { if (el.classList) { el.classList.remove(className); } else { el.className = el.className.replace(new RegExp(`(?:^|\\s)${className}(?!\\S)`, 'g'), ''); } }