+++ /dev/null
-// detect-zoom is dual-licensed under the WTFPL and MIT license,
-// at the recipient's choice.
-// https://github.com/yonran/detect-zoom/
-var DetectZoom = {
- mediaQueryBinarySearch: function(
- property, unit, a, b, maxIter, epsilon) {
- var matchMedia;
- var head, style, div
- if (window.matchMedia) {
- matchMedia = window.matchMedia;
- } else {
- head = document.getElementsByTagName('head')[0];
- style = document.createElement('style');
- div = document.createElement('div');
- div.className = 'mediaQueryBinarySearch';
- head.appendChild(style);
- div.style.display = 'none';
- document.body.appendChild(div);
- matchMedia = function(query) {
- style.sheet.insertRule('@media ' + query +
- '{.mediaQueryBinarySearch ' +
- '{text-decoration: underline} }', 0);
- var matched = getComputedStyle(div, null).textDecoration
- == 'underline';
- style.sheet.deleteRule(0);
- return {matches: matched};
- }
- }
- var r = binarySearch(a, b, maxIter);
- if (div) {
- head.removeChild(style);
- document.body.removeChild(div);
- }
- return r;
-
- function binarySearch(a, b, maxIter) {
- var mid = (a + b) / 2;
- if (maxIter == 0 || b - a < epsilon)
- return mid;
- var query = "(" + property + ":" + mid + unit + ")";
- if (matchMedia(query).matches) {
- return binarySearch(mid, b, maxIter - 1);
- } else {
- return binarySearch(a, mid, maxIter - 1);
- }
- }
- },
- _zoomIe7: function() {
- // the trick: body's offsetWidth was in CSS pixels, while
- // getBoundingClientRect() was in system pixels in IE7.
- // Thanks to http://help.dottoro.com/ljgshbne.php
- var rect = document.body.getBoundingClientRect();
- var z = (rect.right - rect.left) / document.body.offsetWidth;
- z = Math.round(z * 100) / 100;
- return {zoom: z, devicePxPerCssPx: z};
- },
- _zoomIe8: function() {
- // IE 8+: no trick needed!
- // TODO: MSDN says that logicalXDPI and deviceXDPI existed since IE6
- // (which didn't even have whole-page zoom). Check to see whether
- // this method would also work in IE7.
- var zoom = screen.deviceXDPI / screen.logicalXDPI;
- return {
- zoom: zoom,
- devicePxPerCssPx: zoom
- };
- },
- _zoomWebkitMobile: function() {
- // the trick: window.innerWIdth is in CSS pixels, while
- // screen.width and screen.height are in system pixels.
- // And there are no scrollbars to mess up the measurement.
- var devicePixelRatio = window.devicePixelRatio != null ? window.devicePixelRatio : 1
- , deviceWidth;
- if (Math.abs(window.orientation) == 90) {
- deviceWidth = screen.height;
- } else {
- deviceWidth = screen.width;
- }
- var z = deviceWidth / window.innerWidth;
- // return immediately; don't round at the end.
- return {zoom: z, devicePxPerCssPx: z * devicePixelRatio};
- },
- _zoomWebkit: function() {
- // the trick: an element's clientHeight is in CSS pixels, while you can
- // set its line-height in system pixels using font-size and
- // -webkit-text-size-adjust:none.
- // device-pixel-ratio: http://www.webkit.org/blog/55/high-dpi-web-sites/
-
- // Previous trick (used before http://trac.webkit.org/changeset/100847):
- // documentElement.scrollWidth is in CSS pixels, while
- // document.width was in system pixels. Note that this is the
- // layout width of the document, which is slightly different from viewport
- // because document width does not include scrollbars and might be wider
- // due to big elements.
-
- var devicePixelRatio = window.devicePixelRatio != null ? window.devicePixelRatio : 1;
-
- // The container exists so that the div will be laid out in its own flow
- // while not impacting the layout, viewport size, or display of the
- // webpage as a whole.
- var container = document.createElement('div')
- , div = document.createElement('div');
-
- // Add !important and relevant CSS rule resets
- // so that other rules cannot affect the results.
- var important = function(str) {
- return str.replace(/;/g, " !important;");
- };
-
- container.setAttribute('style', important('width:0; height:0; overflow:hidden; visibility:hidden; position: absolute;'));
- div.innerHTML = "1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>0";
- div.setAttribute('style', important('font: 100px/1em sans-serif; -webkit-text-size-adjust: none; height: auto; width: 1em; padding: 0; overflow: visible;'));
-
- container.appendChild(div);
- document.body.appendChild(container);
- var z = 1000 / div.clientHeight;
- z = Math.round(z * 100) / 100;
- var r = {
- zoom: z,
- devicePxPerCssPx: devicePixelRatio * z
- };
- document.body.removeChild(container);
- return r;
- },
- _zoomFF35: function() {
- // the trick for FF3.5 ONLY: device-width gives CSS pixels, while
- // screen.width gave system pixels. Thanks to QuirksMode's widths table,
- // which called it a bug. http://www.quirksmode.org/m/widths.html
- var z = screen.width /
- this.mediaQueryBinarySearch('min-device-width', 'px', 0, 6000, 20, .0001);
- z = Math.round(z * 100) / 100;
- return {zoom: z, devicePxPerCssPx: z};
- },
- _zoomFF36: function() {
- // the hack for FF3.6: you can measure scrollbar's width in CSS pixels,
- // while in system pixels it's 15px (verified in Ubuntu).
-
- // TODO: verify for every platform that a scrollbar is exactly 15px wide.
- var container = document.createElement('div')
- , outerDiv = document.createElement('div');
- // The container exists so that the div will be laid out in its own flow
- // while not impacting the layout, viewport size, or display of the
- // webpage as a whole.
- container.setAttribute('style', 'width:0; height:0; overflow:hidden;' +
- 'visibility:hidden; position: absolute');
- outerDiv.style.width = outerDiv.style.height = '500px'; // enough for all the scrollbars
- var div = outerDiv;
- for (var i = 0; i < 10; ++i) {
- var child = document.createElement('div');
- child.style.overflowY = 'scroll';
- div.appendChild(child);
- div = child;
- }
- container.appendChild(outerDiv);
- document.body.appendChild(container);
- var outerDivWidth = outerDiv.clientWidth;
- var innerDivWidth = div.clientWidth;
- var scrollbarWidthCss = (outerDivWidth - innerDivWidth) / 10;
- document.body.removeChild(container);
- var scrollbarWidthDevice = 15; // Mac and Linux: scrollbars are 15px wide
- if (-1 != navigator.platform.indexOf('Win')) {
- scrollbarWidthDevice = 17;
- }
- var z = scrollbarWidthDevice / scrollbarWidthCss;
- z = Math.round(z * 100) / 100;
- return {zoom: z, devicePxPerCssPx: z};
- },
- _zoomFF4: function() {
- // no real trick; device-pixel-ratio is the ratio of device dpi / css dpi.
- // (Note that this is a different interpretation than Webkit's device
- // pixel ratio, which is the ratio device dpi / system dpi).
- // TODO: is mozmm vs. mm promising?
- var z = this.mediaQueryBinarySearch(
- 'min--moz-device-pixel-ratio',
- '', 0, 10, 20, .0001);
- z = Math.round(z * 100) / 100;
- return {zoom: z, devicePxPerCssPx: z};
- },
- _zoomOperaOlder: function() {
- // 10.00 (or before) to 11.01:
- // the trick: a div with position:fixed;width:100%'s offsetWidth is the
- // viewport width in CSS pixels, while window.innerWidth was in system
- // pixels. Thanks to:
- // http://virtuelvis.com/2005/05/how-to-detect-zoom-level-in-opera/
- // TODO: fix bug: when there is a scrollbar, fixed div does NOT
- // include the scrollbar, while window.outerWidth DOES. This causes the
- // calculation to be off by a few percent.
- var fixedDiv = document.createElement('div');
- fixedDiv.style.position = 'fixed';
- fixedDiv.style.width = '100%';
- fixedDiv.style.height = '100%';
- fixedDiv.style.top = fixedDiv.style.left = '0';
- fixedDiv.style.visibility = 'hidden';
- document.body.appendChild(fixedDiv);
- var z = window.innerWidth / fixedDiv.offsetWidth;
- document.body.removeChild(fixedDiv);
- return {zoom: z, devicePxPerCssPx: z};
- },
- _zoomOpera11: function() {
- // works starting Opera 11.11
- // the trick: outerWidth is the viewport width including scrollbars in
- // system px, while innerWidth is the viewport width including scrollbars
- // in CSS px;
- var z = window.outerWidth / window.innerWidth;
- z = Math.round(z * 100) / 100;
- return {zoom: z, devicePxPerCssPx: z};
- },
- ratios: function() {
- var r;
- if (Modernizr.ftouch) {
- return this._zoomWebkitMobile();
- } else if (!isNaN(screen.logicalXDPI) && !isNaN(screen.systemXDPI)) {
- return this._zoomIe8();
- } else if ('ontouchstart' in window && document.body.style.webkitTextSizeAdjust != null) {
- return this._zoomWebkitMobile();
- } else if (document.body.style.webkitTextSizeAdjust != null) { // webkit
- return this._zoomWebkit();
- } else if (-1 != navigator.userAgent.indexOf('Firefox/3.5')) {
- return this._zoomFF35();
- } else if (-1 != navigator.userAgent.indexOf('Firefox/3.6')) {
- return this._zoomFF36();
- } else if (-1 != navigator.appVersion.indexOf("MSIE 7.")) {
- return this._zoomIe7();
- } else if (-1 != navigator.userAgent.indexOf('Opera')) {
- var versionIdx = navigator.userAgent.indexOf('Version/');
- if (11.01 < parseFloat(navigator.userAgent.substr(versionIdx + 8)))
- return this._zoomOpera11();
- else
- return this._zoomOperaOlder();
- } else if (0.001 < (r = this._zoomFF4()).zoom) {
- return r;
- } else {
- return {zoom: 1, devicePxPerCssPx: 1}
- }
- },
- zoom: function() {
- return this.ratios().zoom;
- },
- device: function() {
- return this.ratios().devicePxPerCssPx;
- }
-};
\ No newline at end of file
/**
- * interact.js v1.2.6
+ * interact.js v1.2.8
*
* Copyright (c) 2012-2015 Taye Adeyemi <dev@taye.me>
* Open source under the MIT License.
supportsTouch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch),
// Does the browser support PointerEvents
- supportsPointerEvent = !!PointerEvent,
+ // Avoid PointerEvent bugs introduced in Chrome 55
+ supportsPointerEvent = PointerEvent && !/Chrome/.test(navigator.userAgent),
// Less Precision with touch input
margin = supportsTouch || supportsPointerEvent? 20: 10,
// Check if is IE9 or older
actionCursors = (document.all && !window.atob) ? {
- drag : 'move',
- resizex : 'e-resize',
- resizey : 's-resize',
- resizexy: 'se-resize',
-
- resizetop : 'n-resize',
- resizeleft : 'w-resize',
- resizebottom : 's-resize',
- resizeright : 'e-resize',
- resizetopleft : 'se-resize',
- resizebottomright: 'se-resize',
- resizetopright : 'ne-resize',
- resizebottomleft : 'ne-resize',
-
- gesture : ''
- } : {
- drag : 'move',
- resizex : 'ew-resize',
- resizey : 'ns-resize',
- resizexy: 'nwse-resize',
-
- resizetop : 'ns-resize',
- resizeleft : 'ew-resize',
- resizebottom : 'ns-resize',
- resizeright : 'ew-resize',
- resizetopleft : 'nwse-resize',
- resizebottomright: 'nwse-resize',
- resizetopright : 'nesw-resize',
- resizebottomleft : 'nesw-resize',
-
- gesture : ''
- },
+ drag : 'move',
+ resizex : 'e-resize',
+ resizey : 's-resize',
+ resizexy: 'se-resize',
+
+ resizetop : 'n-resize',
+ resizeleft : 'w-resize',
+ resizebottom : 's-resize',
+ resizeright : 'e-resize',
+ resizetopleft : 'se-resize',
+ resizebottomright: 'se-resize',
+ resizetopright : 'ne-resize',
+ resizebottomleft : 'ne-resize',
+
+ gesture : ''
+ } : {
+ drag : 'move',
+ resizex : 'ew-resize',
+ resizey : 'ns-resize',
+ resizexy: 'nwse-resize',
+
+ resizetop : 'ns-resize',
+ resizeleft : 'ew-resize',
+ resizebottom : 'ns-resize',
+ resizeright : 'ew-resize',
+ resizetopleft : 'nwse-resize',
+ resizebottomright: 'nwse-resize',
+ resizetopright : 'nesw-resize',
+ resizebottomleft : 'nesw-resize',
+
+ gesture : ''
+ },
actionIsEnabled = {
drag : true,
targets.push(target);
attachedListeners.push((useAttachEvent ? {
- supplied: [],
- wrapped : [],
- useCount: []
- } : null));
+ supplied: [],
+ wrapped : [],
+ useCount: []
+ } : null));
}
if (!target.events[type]) {
this.pointerHover(pointer, event, this.matches, this.matchElements);
events.add(eventTarget,
- PointerEvent? pEventTypes.move : 'mousemove',
+ supportsPointerEvent? pEventTypes.move : 'mousemove',
listeners.pointerHover);
}
else if (this.target) {
if (nodeContains(prevTargetElement, eventTarget)) {
this.pointerHover(pointer, event, this.matches, this.matchElements);
events.add(this.element,
- PointerEvent? pEventTypes.move : 'mousemove',
+ supportsPointerEvent? pEventTypes.move : 'mousemove',
listeners.pointerHover);
}
else {
// Remove temporary event listeners for selector Interactables
if (!interactables.get(eventTarget)) {
events.remove(eventTarget,
- PointerEvent? pEventTypes.move : 'mousemove',
+ supportsPointerEvent? pEventTypes.move : 'mousemove',
listeners.pointerHover);
}
// If it is the second touch of a multi-touch gesture, keep the
// target the same and get a new action if a target was set by the
// first touch
- if (this.pointerIds.length > 1 && this.target._element === this.element) {
+ if (this.pointerIds.length > 1 && this.target && this.target._element && this.target._element === this.element) {
var newAction = validateAction(forceAction || this.target.getAction(pointer, event, this, this.element), this.target);
if (withinInteractionLimit(this.target, this.element, newAction)) {
*
* Start an action with the given Interactable and Element as tartgets. The
* action must be enabled for the target Interactable and an appropriate number
- * of pointers must be held down – 1 for drag/resize, 2 for gesture.
+ * of pointers must be held down – 1 for drag/resize, 2 for gesture.
*
* Use it with `interactable.<action>able({ manualStart: false })` to always
* [start actions manually](https://github.com/taye/interact.js/issues/114)
// set the startCoords if there was no prepared action
if (!this.prepared.name) {
- this.setEventXY(this.startCoords);
+ this.setEventXY(this.startCoords, this.pointers);
}
this.prepared.name = action.name;
pointerEvent.type = eventType;
pointerEvent.pointerId = getPointerId(pointer);
pointerEvent.pointerType = this.mouse? 'mouse' : !supportsPointerEvent? 'touch'
- : isString(pointer.pointerType)
- ? pointer.pointerType
- : [,,'touch', 'pen', 'mouse'][pointer.pointerType];
+ : isString(pointer.pointerType)
+ ? pointer.pointerType
+ : [,,'touch', 'pen', 'mouse'][pointer.pointerType];
}
if (eventType === 'tap') {
if (isElement(element, _window)) {
- if (PointerEvent) {
+ if (supportsPointerEvent) {
events.add(this._element, pEventTypes.down, listeners.pointerDown );
events.add(this._element, pEventTypes.move, listeners.pointerHover);
}
events.add(doc, eventType, delegateUseCapture, true);
}
- if (PointerEvent) {
+ if (supportsPointerEvent) {
if (PointerEvent === win.MSPointerEvent) {
pEventTypes = {
up: 'MSPointerUp', down: 'MSPointerDown', over: 'mouseover',
realWindow.interact = interact;
}
-} (typeof window === 'undefined'? undefined : window));
\ No newline at end of file
+} (typeof window === 'undefined'? undefined : window));