| 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..43807bbc6ad88726764b352b172ac5522c5b1616
|
| --- /dev/null
|
| +++ b/chrome/browser/resources/shared/js/cr/ui/repeating_button.js
|
| @@ -0,0 +1,152 @@
|
| +// 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');
|
| +
|
| + /**
|
| + * DOM Events that may be fired by the Repeating button.
|
| + */
|
| + RepeatingButton.Event = {
|
| + BUTTON_HELD: 'buttonHeld'
|
| + };
|
| +
|
| + 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.addEventListener('mousedown', this.buttonDown_.bind(this));
|
| + this.addEventListener('mouseup', this.buttonUp_.bind(this));
|
| + this.addEventListener('mouseout', this.buttonUp_.bind(this));
|
| + this.addEventListener('touchstart', this.touchStart_.bind(this));
|
| + this.addEventListener('touchend', this.buttonUp_.bind(this));
|
| + this.addEventListener('touchcancel', 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),
|
| + 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() {
|
| + cr.dispatchSimpleEvent(this, RepeatingButton.Event.BUTTON_HELD);
|
| + }
|
| + };
|
| +
|
| + return {
|
| + RepeatingButton: RepeatingButton
|
| + };
|
| +});
|
| +
|
|
|