Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Side by Side Diff: third_party/google_input_tools/src/chrome/os/inputview/handler/pointeractionbundle.js

Issue 674153004: Add third_party/google-input-tools: Take 2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@google_input_tools
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The ChromeOS IME Authors. All Rights Reserved.
2 // limitations under the License.
3 // See the License for the specific language governing permissions and
4 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5 // distributed under the License is distributed on an "AS-IS" BASIS,
6 // Unless required by applicable law or agreed to in writing, software
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // You may obtain a copy of the License at
11 // you may not use this file except in compliance with the License.
12 // Licensed under the Apache License, Version 2.0 (the "License");
13 //
14 goog.provide('i18n.input.chrome.inputview.handler.PointerActionBundle');
15
16 goog.require('goog.Timer');
17 goog.require('goog.dom');
18 goog.require('goog.events.EventTarget');
19 goog.require('goog.events.EventType');
20 goog.require('goog.math.Coordinate');
21 goog.require('i18n.input.chrome.inputview.SwipeDirection');
22 goog.require('i18n.input.chrome.inputview.events.DragEvent');
23 goog.require('i18n.input.chrome.inputview.events.EventType');
24 goog.require('i18n.input.chrome.inputview.events.PointerEvent');
25 goog.require('i18n.input.chrome.inputview.events.SwipeEvent');
26 goog.require('i18n.input.chrome.inputview.handler.SwipeState');
27
28
29
30 goog.scope(function() {
31
32
33
34 /**
35 * The handler for long press.
36 *
37 * @param {!Node} target The target for this pointer event.
38 * @param {goog.events.EventTarget=} opt_parentEventTarget The parent event
39 * target.
40 * @constructor
41 * @extends {goog.events.EventTarget}
42 */
43 i18n.input.chrome.inputview.handler.PointerActionBundle = function(target,
44 opt_parentEventTarget) {
45 goog.base(this);
46 this.setParentEventTarget(opt_parentEventTarget || null);
47
48 /**
49 * The target.
50 *
51 * @type {i18n.input.chrome.inputview.elements.Element}
52 * @private
53 */
54 this.view_ = this.getView_(target);
55
56 /**
57 * The swipe offset.
58 *
59 * @type {!i18n.input.chrome.inputview.handler.SwipeState}
60 * @private
61 */
62 this.swipeState_ = new i18n.input.chrome.inputview.handler.SwipeState();
63 };
64 goog.inherits(i18n.input.chrome.inputview.handler.PointerActionBundle,
65 goog.events.EventTarget);
66 var PointerActionBundle = i18n.input.chrome.inputview.handler.
67 PointerActionBundle;
68
69
70 /**
71 * The current target after the touch point is moved.
72 *
73 * @type {!Node | Element}
74 * @private
75 */
76 PointerActionBundle.prototype.currentTarget_;
77
78
79 /**
80 * How many milli-seconds to evaluate a double click event.
81 *
82 * @type {number}
83 * @private
84 */
85 PointerActionBundle.DOUBLE_CLICK_INTERVAL_ = 500;
86
87
88 /**
89 * The timer ID.
90 *
91 * @type {number}
92 * @private
93 */
94 PointerActionBundle.prototype.longPressTimer_;
95
96
97 /**
98 * The minimum swipe distance.
99 *
100 * @type {number}
101 * @private
102 */
103 PointerActionBundle.MINIMUM_SWIPE_DISTANCE_ = 20;
104
105
106 /**
107 * The timestamp of the pointer down.
108 *
109 * @type {number}
110 * @private
111 */
112 PointerActionBundle.prototype.pointerDownTimeStamp_ = 0;
113
114
115 /**
116 * The timestamp of the pointer up.
117 *
118 * @type {number}
119 * @private
120 */
121 PointerActionBundle.prototype.pointerUpTimeStamp_ = 0;
122
123
124 /**
125 * True if it is double clicking.
126 *
127 * @type {boolean}
128 * @private
129 */
130 PointerActionBundle.prototype.isDBLClicking_ = false;
131
132
133 /**
134 * True if it is long pressing.
135 *
136 * @type {boolean}
137 * @private
138 */
139 PointerActionBundle.prototype.isLongPressing_ = false;
140
141
142 /**
143 * True if it is flickering.
144 *
145 * @type {boolean}
146 * @private
147 */
148 PointerActionBundle.prototype.isFlickering_ = false;
149
150
151 /**
152 * Gets the view.
153 *
154 * @param {Node} target .
155 * @return {i18n.input.chrome.inputview.elements.Element} .
156 * @private
157 */
158 PointerActionBundle.prototype.getView_ = function(target) {
159 if (!target) {
160 return null;
161 }
162 var element = /** @type {!Element} */ (target);
163 var view = element['view'];
164 while (!view && element) {
165 view = element['view'];
166 element = goog.dom.getParentElement(element);
167 }
168 return view;
169 };
170
171
172 /**
173 * Handles touchmove event for one target.
174 *
175 * @param {!Event} touchEvent .
176 */
177 PointerActionBundle.prototype.handleTouchMove = function(touchEvent) {
178 var direction = 0;
179 var deltaX = this.swipeState_.previousX == 0 ? 0 : (touchEvent.pageX -
180 this.swipeState_.previousX);
181 var deltaY = this.swipeState_.previousY == 0 ? 0 :
182 (touchEvent.pageY - this.swipeState_.previousY);
183 this.swipeState_.offsetX += deltaX;
184 this.swipeState_.offsetY += deltaY;
185 this.dispatchEvent(new i18n.input.chrome.inputview.events.DragEvent(
186 this.view_, direction, /** @type {!Node} */ (touchEvent.target),
187 touchEvent.pageX, touchEvent.pageY, deltaX, deltaY));
188
189 var minimumSwipeDist = PointerActionBundle.
190 MINIMUM_SWIPE_DISTANCE_;
191
192 if (this.swipeState_.offsetX > minimumSwipeDist) {
193 direction |= i18n.input.chrome.inputview.SwipeDirection.RIGHT;
194 this.swipeState_.offsetX = 0;
195 } else if (this.swipeState_.offsetX < -minimumSwipeDist) {
196 direction |= i18n.input.chrome.inputview.SwipeDirection.LEFT;
197 this.swipeState_.offsetX = 0;
198 }
199
200 if (Math.abs(deltaY) > Math.abs(deltaX)) {
201 if (this.swipeState_.offsetY > minimumSwipeDist) {
202 direction |= i18n.input.chrome.inputview.SwipeDirection.DOWN;
203 this.swipeState_.offsetY = 0;
204 } else if (this.swipeState_.offsetY < -minimumSwipeDist) {
205 direction |= i18n.input.chrome.inputview.SwipeDirection.UP;
206 this.swipeState_.offsetY = 0;
207 }
208 }
209
210 this.swipeState_.previousX = touchEvent.pageX;
211 this.swipeState_.previousY = touchEvent.pageY;
212
213 if (direction > 0) {
214 // If there is any movement, cancel the longpress timer.
215 goog.Timer.clear(this.longPressTimer_);
216 this.dispatchEvent(new i18n.input.chrome.inputview.events.SwipeEvent(
217 this.view_, direction, /** @type {!Node} */ (touchEvent.target),
218 touchEvent.pageX, touchEvent.pageY));
219 var currentTargetView = this.getView_(this.currentTarget_);
220 if (this.view_) {
221 this.isFlickering_ = !this.isLongPressing_ && !!(this.view_.pointerConfig.
222 flickerDirection & direction) && currentTargetView == this.view_;
223 }
224 }
225
226 this.maybeSwitchTarget_(touchEvent);
227 };
228
229
230 /**
231 * If the target is switched to a new one, sends out a pointer_over for the new
232 * target and sends out a pointer_out for the old target.
233 *
234 * @param {!Event | !goog.events.BrowserEvent} e .
235 * @private
236 */
237 PointerActionBundle.prototype.maybeSwitchTarget_ = function(e) {
238 if (!this.isFlickering_) {
239 var pageOffset = this.getPageOffset_(e);
240 var actualTarget = document.elementFromPoint(pageOffset.x, pageOffset.y);
241 var currentTargetView = this.getView_(this.currentTarget_);
242 var actualTargetView = this.getView_(actualTarget);
243 if (currentTargetView != actualTargetView) {
244 if (currentTargetView) {
245 this.dispatchEvent(new i18n.input.chrome.inputview.events.PointerEvent(
246 currentTargetView,
247 i18n.input.chrome.inputview.events.EventType.POINTER_OUT,
248 this.currentTarget_, pageOffset.x, pageOffset.y));
249 }
250 if (actualTargetView) {
251 this.dispatchEvent(new i18n.input.chrome.inputview.events.PointerEvent(
252 actualTargetView,
253 i18n.input.chrome.inputview.events.EventType.POINTER_OVER,
254 actualTarget, pageOffset.x, pageOffset.y));
255 }
256 this.currentTarget_ = actualTarget;
257 }
258 }
259 };
260
261
262 /**
263 * Handles pointer up, e.g., mouseup/touchend.
264 *
265 * @param {!goog.events.BrowserEvent} e The event.
266 */
267 PointerActionBundle.prototype.handlePointerUp = function(e) {
268 goog.Timer.clear(this.longPressTimer_);
269 var pageOffset = this.getPageOffset_(e);
270 this.dispatchEvent(new i18n.input.chrome.inputview.events.PointerEvent(
271 this.view_, i18n.input.chrome.inputview.events.EventType.LONG_PRESS_END,
272 e.target, pageOffset.x, pageOffset.y));
273 if (this.isDBLClicking_) {
274 this.dispatchEvent(new i18n.input.chrome.inputview.events.PointerEvent(
275 this.view_, i18n.input.chrome.inputview.events.EventType.
276 DOUBLE_CLICK_END, e.target, pageOffset.x, pageOffset.y));
277 } else if (!(this.isLongPressing_ && this.view_.pointerConfig.
278 longPressWithoutPointerUp)) {
279 if (this.isLongPressing_) {
280 // If the finger didn't move but it triggers a longpress, it could cause
281 // a target switch, so checks it here.
282 this.maybeSwitchTarget_(e);
283 }
284 var view = this.getView_(this.currentTarget_);
285 var target = this.currentTarget_;
286 if (this.isFlickering_) {
287 view = this.view_;
288 target = e.target;
289 }
290 if (view) {
291 this.pointerUpTimeStamp_ = new Date().getTime();
292 this.dispatchEvent(new i18n.input.chrome.inputview.events.PointerEvent(
293 view, i18n.input.chrome.inputview.events.EventType.POINTER_UP,
294 target, pageOffset.x, pageOffset.y, this.pointerUpTimeStamp_));
295 }
296 }
297 if (this.getView_(this.currentTarget_) == this.view_) {
298 this.dispatchEvent(new i18n.input.chrome.inputview.events.PointerEvent(
299 this.view_, i18n.input.chrome.inputview.events.EventType.CLICK,
300 e.target, pageOffset.x, pageOffset.y));
301 }
302 this.isDBLClicking_ = false;
303 this.isLongPressing_ = false;
304 this.isFlickering_ = false;
305 this.swipeState_.reset();
306
307 e.preventDefault();
308 if (this.view_ && this.view_.pointerConfig.stopEventPropagation) {
309 e.stopPropagation();
310 }
311 };
312
313
314 /**
315 * Cancel double click recognition on this target.
316 */
317 PointerActionBundle.prototype.cancelDoubleClick = function() {
318 this.pointerDownTimeStamp_ = 0;
319 };
320
321
322 /**
323 * Handles pointer down, e.g., mousedown/touchstart.
324 *
325 * @param {!goog.events.BrowserEvent} e The event.
326 */
327 PointerActionBundle.prototype.handlePointerDown = function(e) {
328 this.currentTarget_ = e.target;
329 goog.Timer.clear(this.longPressTimer_);
330 if (e.type != goog.events.EventType.MOUSEDOWN) {
331 // Don't trigger long press for mouse event.
332 this.maybeTriggerKeyDownLongPress_(e);
333 }
334 this.maybeHandleDBLClick_(e);
335 if (!this.isDBLClicking_) {
336 var pageOffset = this.getPageOffset_(e);
337 this.dispatchEvent(new i18n.input.chrome.inputview.events.PointerEvent(
338 this.view_, i18n.input.chrome.inputview.events.EventType.POINTER_DOWN,
339 e.target, pageOffset.x, pageOffset.y, this.pointerDownTimeStamp_));
340 }
341
342 if (this.view_ && this.view_.pointerConfig.preventDefault) {
343 e.preventDefault();
344 }
345 if (this.view_ && this.view_.pointerConfig.stopEventPropagation) {
346 e.stopPropagation();
347 }
348 };
349
350
351 /**
352 * Gets the page offset from the event which may be mouse event or touch event.
353 *
354 * @param {!goog.events.BrowserEvent | !TouchEvent | !Event} e .
355 * @return {!goog.math.Coordinate} .
356 * @private
357 */
358 PointerActionBundle.prototype.getPageOffset_ = function(e) {
359 if (e.pageX && e.pageY) {
360 return new goog.math.Coordinate(e.pageX, e.pageY);
361 }
362
363 if (!e.getBrowserEvent) {
364 return new goog.math.Coordinate(0, 0);
365 }
366
367 var nativeEvt = e.getBrowserEvent();
368 if (nativeEvt.pageX && nativeEvt.pageY) {
369 return new goog.math.Coordinate(nativeEvt.pageX, nativeEvt.pageY);
370 }
371
372
373 var touchEventList = nativeEvt['changedTouches'];
374 if (!touchEventList || touchEventList.length == 0) {
375 touchEventList = nativeEvt['touches'];
376 }
377 if (touchEventList && touchEventList.length > 0) {
378 var touchEvent = touchEventList[0];
379 return new goog.math.Coordinate(touchEvent.pageX, touchEvent.pageY);
380 }
381
382 return new goog.math.Coordinate(0, 0);
383 };
384
385
386 /**
387 * Maybe triggers the long press timer when pointer down.
388 *
389 * @param {!goog.events.BrowserEvent} e The event.
390 * @private
391 */
392 PointerActionBundle.prototype.maybeTriggerKeyDownLongPress_ = function(e) {
393 if (this.view_ && (this.view_.pointerConfig.longPressWithPointerUp ||
394 this.view_.pointerConfig.longPressWithoutPointerUp)) {
395 this.longPressTimer_ = goog.Timer.callOnce(
396 goog.bind(this.triggerLongPress_, this, e),
397 this.view_.pointerConfig.longPressDelay, this);
398 }
399 };
400
401
402 /**
403 * Maybe handle the double click.
404 *
405 * @param {!goog.events.BrowserEvent} e .
406 * @private
407 */
408 PointerActionBundle.prototype.maybeHandleDBLClick_ = function(e) {
409 if (this.view_ && this.view_.pointerConfig.dblClick) {
410 var timeInMs = new Date().getTime();
411 var interval = this.view_.pointerConfig.dblClickDelay ||
412 PointerActionBundle.DOUBLE_CLICK_INTERVAL_;
413 var nativeEvt = e.getBrowserEvent();
414 if ((timeInMs - this.pointerDownTimeStamp_) < interval) {
415 this.dispatchEvent(new i18n.input.chrome.inputview.events.PointerEvent(
416 this.view_, i18n.input.chrome.inputview.events.EventType.DOUBLE_CLICK,
417 e.target, nativeEvt.pageX, nativeEvt.pageY));
418 this.isDBLClicking_ = true;
419 }
420 this.pointerDownTimeStamp_ = timeInMs;
421 }
422 };
423
424
425 /**
426 * Triggers long press event.
427 *
428 * @param {!goog.events.BrowserEvent} e The event.
429 * @private
430 */
431 PointerActionBundle.prototype.triggerLongPress_ = function(e) {
432 var nativeEvt = e.getBrowserEvent();
433 this.dispatchEvent(new i18n.input.chrome.inputview.events.PointerEvent(
434 this.view_, i18n.input.chrome.inputview.events.EventType.LONG_PRESS,
435 e.target, nativeEvt.pageX, nativeEvt.pageY));
436 this.isLongPressing_ = true;
437 };
438
439
440 /** @override */
441 PointerActionBundle.prototype.disposeInternal = function() {
442 goog.dispose(this.longPressTimer_);
443
444 goog.base(this, 'disposeInternal');
445 };
446
447 }); // goog.scope
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698