1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | "use strict";
|
23 |
|
24 | Object.defineProperty(exports, "__esModule", {
|
25 | value: true
|
26 | });
|
27 | exports.GrabToPan = GrabToPan;
|
28 |
|
29 | function GrabToPan(options) {
|
30 | this.element = options.element;
|
31 | this.document = options.element.ownerDocument;
|
32 |
|
33 | if (typeof options.ignoreTarget === 'function') {
|
34 | this.ignoreTarget = options.ignoreTarget;
|
35 | }
|
36 |
|
37 | this.onActiveChanged = options.onActiveChanged;
|
38 | this.activate = this.activate.bind(this);
|
39 | this.deactivate = this.deactivate.bind(this);
|
40 | this.toggle = this.toggle.bind(this);
|
41 | this._onmousedown = this._onmousedown.bind(this);
|
42 | this._onmousemove = this._onmousemove.bind(this);
|
43 | this._endPan = this._endPan.bind(this);
|
44 | var overlay = this.overlay = document.createElement('div');
|
45 | overlay.className = 'grab-to-pan-grabbing';
|
46 | }
|
47 |
|
48 | GrabToPan.prototype = {
|
49 | CSS_CLASS_GRAB: 'grab-to-pan-grab',
|
50 | activate: function GrabToPan_activate() {
|
51 | if (!this.active) {
|
52 | this.active = true;
|
53 | this.element.addEventListener('mousedown', this._onmousedown, true);
|
54 | this.element.classList.add(this.CSS_CLASS_GRAB);
|
55 |
|
56 | if (this.onActiveChanged) {
|
57 | this.onActiveChanged(true);
|
58 | }
|
59 | }
|
60 | },
|
61 | deactivate: function GrabToPan_deactivate() {
|
62 | if (this.active) {
|
63 | this.active = false;
|
64 | this.element.removeEventListener('mousedown', this._onmousedown, true);
|
65 |
|
66 | this._endPan();
|
67 |
|
68 | this.element.classList.remove(this.CSS_CLASS_GRAB);
|
69 |
|
70 | if (this.onActiveChanged) {
|
71 | this.onActiveChanged(false);
|
72 | }
|
73 | }
|
74 | },
|
75 | toggle: function GrabToPan_toggle() {
|
76 | if (this.active) {
|
77 | this.deactivate();
|
78 | } else {
|
79 | this.activate();
|
80 | }
|
81 | },
|
82 | ignoreTarget: function GrabToPan_ignoreTarget(node) {
|
83 | return node[matchesSelector]('a[href], a[href] *, input, textarea, button, button *, select, option');
|
84 | },
|
85 | _onmousedown: function GrabToPan__onmousedown(event) {
|
86 | if (event.button !== 0 || this.ignoreTarget(event.target)) {
|
87 | return;
|
88 | }
|
89 |
|
90 | if (event.originalTarget) {
|
91 | try {
|
92 | event.originalTarget.tagName;
|
93 | } catch (e) {
|
94 | return;
|
95 | }
|
96 | }
|
97 |
|
98 | this.scrollLeftStart = this.element.scrollLeft;
|
99 | this.scrollTopStart = this.element.scrollTop;
|
100 | this.clientXStart = event.clientX;
|
101 | this.clientYStart = event.clientY;
|
102 | this.document.addEventListener('mousemove', this._onmousemove, true);
|
103 | this.document.addEventListener('mouseup', this._endPan, true);
|
104 | this.element.addEventListener('scroll', this._endPan, true);
|
105 | event.preventDefault();
|
106 | event.stopPropagation();
|
107 | var focusedElement = document.activeElement;
|
108 |
|
109 | if (focusedElement && !focusedElement.contains(event.target)) {
|
110 | focusedElement.blur();
|
111 | }
|
112 | },
|
113 | _onmousemove: function GrabToPan__onmousemove(event) {
|
114 | this.element.removeEventListener('scroll', this._endPan, true);
|
115 |
|
116 | if (isLeftMouseReleased(event)) {
|
117 | this._endPan();
|
118 |
|
119 | return;
|
120 | }
|
121 |
|
122 | var xDiff = event.clientX - this.clientXStart;
|
123 | var yDiff = event.clientY - this.clientYStart;
|
124 | var scrollTop = this.scrollTopStart - yDiff;
|
125 | var scrollLeft = this.scrollLeftStart - xDiff;
|
126 |
|
127 | if (this.element.scrollTo) {
|
128 | this.element.scrollTo({
|
129 | top: scrollTop,
|
130 | left: scrollLeft,
|
131 | behavior: 'instant'
|
132 | });
|
133 | } else {
|
134 | this.element.scrollTop = scrollTop;
|
135 | this.element.scrollLeft = scrollLeft;
|
136 | }
|
137 |
|
138 | if (!this.overlay.parentNode) {
|
139 | document.body.appendChild(this.overlay);
|
140 | }
|
141 | },
|
142 | _endPan: function GrabToPan__endPan() {
|
143 | this.element.removeEventListener('scroll', this._endPan, true);
|
144 | this.document.removeEventListener('mousemove', this._onmousemove, true);
|
145 | this.document.removeEventListener('mouseup', this._endPan, true);
|
146 | this.overlay.remove();
|
147 | }
|
148 | };
|
149 | var matchesSelector;
|
150 | ['webkitM', 'mozM', 'msM', 'oM', 'm'].some(function (prefix) {
|
151 | var name = prefix + 'atches';
|
152 |
|
153 | if (name in document.documentElement) {
|
154 | matchesSelector = name;
|
155 | }
|
156 |
|
157 | name += 'Selector';
|
158 |
|
159 | if (name in document.documentElement) {
|
160 | matchesSelector = name;
|
161 | }
|
162 |
|
163 | return matchesSelector;
|
164 | });
|
165 | var isNotIEorIsIE10plus = !document.documentMode || document.documentMode > 9;
|
166 | var chrome = window.chrome;
|
167 | var isChrome15OrOpera15plus = chrome && (chrome.webstore || chrome.app);
|
168 | var isSafari6plus = /Apple/.test(navigator.vendor) && /Version\/([6-9]\d*|[1-5]\d+)/.test(navigator.userAgent);
|
169 |
|
170 | function isLeftMouseReleased(event) {
|
171 | if ('buttons' in event && isNotIEorIsIE10plus) {
|
172 | return !(event.buttons & 1);
|
173 | }
|
174 |
|
175 | if (isChrome15OrOpera15plus || isSafari6plus) {
|
176 | return event.which === 0;
|
177 | }
|
178 |
|
179 | return false;
|
180 | } |
\ | No newline at end of file |