Index: chrome/browser/resources/shared/js/cr/ui/repeating_button.js |
diff --git a/chrome/browser/resources/shared/js/cr/ui/repeating_button.js b/chrome/browser/resources/shared/js/cr/ui/repeating_button.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b789e5d5ac63c4017e35b7a74b5ade04c2d3a611 |
--- /dev/null |
+++ b/chrome/browser/resources/shared/js/cr/ui/repeating_button.js |
@@ -0,0 +1,145 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+cr.define('cr.ui', function() { |
+ /** |
+ * Creates a new button element. The repeating button behaves like a |
+ * keyboard button, which auto-repeats if held. This button is designed |
+ * for use with controls such as brightness and volume adjustment buttons. |
+ * @constructor |
+ * @extends {HTMLButtonElement} |
+ */ |
+ var RepeatingButton = cr.ui.define('button'); |
+ |
+ RepeatingButton.prototype = { |
+ __proto__: HTMLButtonElement.prototype, |
+ |
+ /** |
+ * Delay in milliseconds before the first repeat trigger of the button |
+ * held action. |
+ * @type {number} |
+ * @private |
+ */ |
+ holdDelayTime_: 500, |
+ |
+ /** |
+ * Delay in milliseconds between triggers of the button held action. |
+ * @type {number} |
+ * @private |
+ */ |
+ holdRepeatIntervalTime_: 50, |
+ |
+ /** |
+ * Callback function when repeated intervals trigger. Initialized when the |
+ * button is held for an initial delay period and cleared when the button |
+ * is released. |
+ * @type {function} |
+ * @private |
+ */ |
+ intervalCallback_: undefined, |
+ |
+ /** |
+ * Callback function to arm the repeat timer. Initialized when the button |
+ * is pressed and cleared when the interval timer is set or the button is |
+ * released. |
+ * @type {function} |
+ * @private |
+ */ |
+ armRepeaterCallback_: undefined, |
+ |
+ /** |
+ * Initializes the button. |
+ */ |
+ decorate: function() { |
+ this.onmousedown = this.buttonDown_.bind(this); |
+ this.onmouseup = this.buttonUp_.bind(this); |
+ this.onmouseout = this.buttonUp_.bind(this); |
+ this.ontouchstart = this.touchStart_.bind(this); |
+ this.ontouchend = this.buttonUp_.bind(this); |
+ this.ontouchcancel = this.buttonUp_.bind(this); |
+ }, |
+ |
+ /** |
+ * Called when the user initiates a touch gesture. |
+ * @param {!Event} e The triggered event. |
+ * @private |
+ */ |
+ touchStart_: function(e) { |
+ // Block system level gestures to prevent double tap to zoom. Also, |
+ // block following mouse event to prevent double firing of the button |
+ // held action in the case of a tap. Otherwise, a single tap action in |
+ // webkit generates the following event sequence: touchstart, touchend, |
+ // mouseover, mousemove, mousedown, mouseup and click. |
+ e.preventDefault(); |
+ this.buttonDown_(e); |
+ }, |
+ |
+ /** |
+ * Called when the user presses this button. |
+ * @param {!Event} e The triggered event. |
+ * @private |
+ */ |
+ buttonDown_: function(e) { |
+ this.clearTimeout_(); |
+ // Trigger the button held action immediately, after an initial delay and |
+ // then repeated based on a fixed time increment. The time intervals are |
+ // in agreement with the defaults for the ChromeOS keyboard and virtual |
+ // keyboard. |
+ // TODO(kevers): Consider adding a common location for picking up the |
+ // initial delay and repeat interval. |
+ this.buttonHeld_(); |
+ var self = this; |
+ this.armRepeaterCallback_ = function() { |
+ // In the event of a click/tap operation, this button has already been |
+ // released by the time this timeout triggers. Test to ensure that the |
+ // button is still being held (i.e. clearTimeout has not been called). |
+ if (self.armRepeaterCallback_) { |
+ self.armRepeaterCallback_ = undefined; |
+ self.intervalCallback_ = setInterval(self.buttonHeld_.bind(self), |
James Hawkins
2011/10/29 22:07:45
nit: Start of params need to line up on the same c
kevers
2011/10/31 19:07:28
Done.
|
+ self.holdRepeatIntervalTime_); |
+ } |
+ }; |
+ setTimeout(this.armRepeaterCallback_, Math.max(0, this.holdDelayTime_ - |
+ this.holdRepeatIntervalTime_)); |
+ }, |
+ |
+ /** |
+ * Called when the user releases this button. |
+ * @param {!Event} e The triggered event. |
+ * @private |
+ */ |
+ buttonUp_: function(e) { |
+ this.clearTimeout_(); |
+ }, |
+ |
+ /** |
+ * Resets the interval callback. |
+ * @private |
+ */ |
+ clearTimeout_: function() { |
+ if (this.armRepeaterCallback_) { |
+ clearTimeout(this.armRepeaterCallback_); |
+ this.armRepeaterCallback_ = undefined; |
+ } |
+ if (this.intervalCallback_) { |
+ clearInterval(this.intervalCallback_); |
+ this.intervalCallback_ = undefined; |
+ } |
+ }, |
+ |
+ /** |
+ * Dispatches the action associated with keeping this button pressed. |
+ * @private |
+ */ |
+ buttonHeld_: function() { |
+ if (this.onButtonHeldAction) |
+ this.onButtonHeldAction(); |
+ } |
+ }; |
+ |
+ return { |
+ RepeatingButton: RepeatingButton |
+ }; |
+}); |
+ |