Permalink
Browse files

Adds isDragging and DragEventType.START/END events to closure slider.

R=nnaze
DELTA=142  (139 added, 0 deleted, 3 changed)


Revision created by MOE tool push_codebase.
MOE_MIGRATION=5775


git-svn-id: http://closure-library.googlecode.com/svn/trunk@2277 0b95b8e8-c90f-11de-9d4f-f947ee5921c8
  • Loading branch information...
1 parent 6047f78 commit 976307d5e04933e58ff25ed0fff926bcfcd8653e fgastellu@google.com committed Nov 7, 2012
Showing with 142 additions and 3 deletions.
  1. +54 −3 closure/goog/ui/sliderbase.js
  2. +88 −0 closure/goog/ui/sliderbase_test.html
@@ -90,6 +90,33 @@ goog.inherits(goog.ui.SliderBase, goog.ui.Component);
/**
+ * Event types used to listen for dragging events. Note that extent drag events
+ * are also sent for single-thumb sliders, since the one thumb controls both
+ * value and extent together; in this case, they can simply be ignored.
+ * @enum {string}
+ */
+goog.ui.SliderBase.EventType = {
+ /** User started dragging the value thumb */
+ DRAG_VALUE_START: goog.events.getUniqueId('dragvaluestart'),
+ /** User is done dragging the value thumb */
+ DRAG_VALUE_END: goog.events.getUniqueId('dragvalueend'),
+ /** User started dragging the extent thumb */
+ DRAG_EXTENT_START: goog.events.getUniqueId('dragextentstart'),
+ /** User is done dragging the extent thumb */
+ DRAG_EXTENT_END: goog.events.getUniqueId('dragextentend'),
+ // Note that the following two events are sent twice, once for the value
+ // dragger, and once of the extent dragger. If you need to differentiate
+ // between the two, or if your code relies on receiving a single event per
+ // START/END event, it should listen to one of the VALUE/EXTENT-specific
+ // events.
+ /** User started dragging a thumb */
+ DRAG_START: goog.events.getUniqueId('dragstart'),
+ /** User is done dragging a thumb */
+ DRAG_END: goog.events.getUniqueId('dragend')
+};
+
+
+/**
* Enum for representing the orientation of the slider.
*
* @enum {string}
@@ -460,11 +487,23 @@ goog.ui.SliderBase.prototype.handleBeforeDrag_ = function(e) {
* @private
*/
goog.ui.SliderBase.prototype.handleThumbDragStartEnd_ = function(e) {
- var enable = e.type == goog.fx.Dragger.EventType.START;
+ var isDragStart = e.type == goog.fx.Dragger.EventType.START;
goog.dom.classes.enable(this.getElement(),
- goog.ui.SliderBase.SLIDER_DRAGGING_CSS_CLASS_, enable);
+ goog.ui.SliderBase.SLIDER_DRAGGING_CSS_CLASS_, isDragStart);
goog.dom.classes.enable(e.target.handle,
- goog.ui.SliderBase.THUMB_DRAGGING_CSS_CLASS_, enable);
+ goog.ui.SliderBase.THUMB_DRAGGING_CSS_CLASS_, isDragStart);
+ var isValueDragger = e.dragger == this.valueDragger_;
+ if (isDragStart) {
+ this.dispatchEvent(goog.ui.SliderBase.EventType.DRAG_START);
+ this.dispatchEvent(isValueDragger ?
+ goog.ui.SliderBase.EventType.DRAG_VALUE_START :
+ goog.ui.SliderBase.EventType.DRAG_EXTENT_START);
+ } else {
+ this.dispatchEvent(goog.ui.SliderBase.EventType.DRAG_END);
+ this.dispatchEvent(isValueDragger ?
+ goog.ui.SliderBase.EventType.DRAG_VALUE_END :
+ goog.ui.SliderBase.EventType.DRAG_EXTENT_END);
+ }
};
@@ -734,6 +773,18 @@ goog.ui.SliderBase.prototype.getThumbPosition_ = function(thumb) {
/**
+ * Returns whether a thumb is currently being dragged with the mouse (or via
+ * touch). Note that changing the value with keyboard, mouswheel, or via
+ * move-to-point click immediately sends a CHANGE event without going through a
+ * dragged state.
+ * @return {boolean} Whether a dragger is currently being dragged.
+ */
+goog.ui.SliderBase.prototype.isDragging = function() {
+ return this.valueDragger_.isDragging() || this.extentDragger_.isDragging();
+};
+
+
+/**
* Moves the thumbs by the specified delta as follows
* - as long as both thumbs stay within [min,max], both thumbs are moved
* - once a thumb reaches or exceeds min (or max, respectively), it stays
@@ -684,6 +684,94 @@
value, Math.round(oneThumbSlider.getValueFromMousePosition(e)));
}
+/**
+ * Tests dragging events.
+ */
+function testDragEvents() {
+ var offset = goog.style.getPageOffset(oneThumbSlider.valueThumb);
+ var size = goog.style.getSize(oneThumbSlider.valueThumb);
+ offset.x += size.width / 2;
+ offset.y += size.height / 2;
+ var event_types = [];
+ var handler = function(evt) {
+ event_types.push(evt.type);
+ }
+
+ goog.events.listen(oneThumbSlider,
+ [goog.ui.SliderBase.EventType.DRAG_START,
+ goog.ui.SliderBase.EventType.DRAG_END,
+ goog.ui.SliderBase.EventType.DRAG_VALUE_START,
+ goog.ui.SliderBase.EventType.DRAG_VALUE_END,
+ goog.ui.SliderBase.EventType.DRAG_EXTENT_START,
+ goog.ui.SliderBase.EventType.DRAG_EXTENT_END,
+ goog.ui.Component.EventType.CHANGE],
+ handler);
+
+ // Since the order of the events between value and extent is not guaranteed
+ // accross browsers, we need to allow for both here and once we have
+ // them all, make sure that they were different.
+ function isValueOrExtentDragStart(type) {
+ return type == goog.ui.SliderBase.EventType.DRAG_VALUE_START ||
+ type == goog.ui.SliderBase.EventType.DRAG_EXTENT_START;
+ };
+ function isValueOrExtentDragEnd(type) {
+ return type == goog.ui.SliderBase.EventType.DRAG_VALUE_END ||
+ type == goog.ui.SliderBase.EventType.DRAG_EXTENT_END;
+ };
+
+ // Test that dragging the thumb calls all the correct events.
+ goog.testing.events.fireMouseDownEvent(oneThumbSlider.valueThumb);
+ offset.x += 100;
+ goog.testing.events.fireMouseMoveEvent(oneThumbSlider.valueThumb, offset);
+ goog.testing.events.fireMouseUpEvent(oneThumbSlider.valueThumb);
+
+ assertEquals(9, event_types.length);
+
+ assertEquals(goog.ui.SliderBase.EventType.DRAG_START, event_types[0]);
+ assertTrue(isValueOrExtentDragStart(event_types[1]));
+
+ assertEquals(goog.ui.SliderBase.EventType.DRAG_START, event_types[2]);
+ assertTrue(isValueOrExtentDragStart(event_types[3]));
+
+ assertEquals(goog.ui.Component.EventType.CHANGE, event_types[4]);
+
+ assertEquals(goog.ui.SliderBase.EventType.DRAG_END, event_types[5]);
+ assertTrue(isValueOrExtentDragEnd(event_types[6]));
+
+ assertEquals(goog.ui.SliderBase.EventType.DRAG_END, event_types[7]);
+ assertTrue(isValueOrExtentDragEnd(event_types[8]));
+
+ assertFalse(event_types[1] == event_types[3]);
+ assertFalse(event_types[6] == event_types[8]);
+
+ // Test that clicking the thumb without moving the mouse does not cause a
+ // CHANGE event between DRAG_START/DRAG_END.
+ event_types = [];
+ goog.testing.events.fireMouseDownEvent(oneThumbSlider.valueThumb);
+ goog.testing.events.fireMouseUpEvent(oneThumbSlider.valueThumb);
+
+ assertEquals(8, event_types.length);
+
+ assertEquals(goog.ui.SliderBase.EventType.DRAG_START, event_types[0]);
+ assertTrue(isValueOrExtentDragStart(event_types[1]));
+
+ assertEquals(goog.ui.SliderBase.EventType.DRAG_START, event_types[2]);
+ assertTrue(isValueOrExtentDragStart(event_types[3]));
+
+ assertEquals(goog.ui.SliderBase.EventType.DRAG_END, event_types[4]);
+ assertTrue(isValueOrExtentDragEnd(event_types[5]));
+
+ assertEquals(goog.ui.SliderBase.EventType.DRAG_END, event_types[6]);
+ assertTrue(isValueOrExtentDragEnd(event_types[7]));
+
+ assertFalse(event_types[1] == event_types[3]);
+ assertFalse(event_types[5] == event_types[7]);
+
+ // Early listener removal, do not wait for tearDown, to avoid building up
+ // arrays of events unnecessarilly in further tests.
+ goog.events.removeAll(oneThumbSlider);
+}
+
</script>
</body>
</html>

0 comments on commit 976307d

Please sign in to comment.