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

Unified Diff: chrome/browser/resources/settings/device_page/drag_behavior.js

Issue 2097793004: MD Settings: Display: Implement dragging (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@issue_547080_display_settings7
Patch Set: Feedback Created 4 years, 6 months 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/settings/device_page/drag_behavior.js
diff --git a/chrome/browser/resources/settings/device_page/drag_behavior.js b/chrome/browser/resources/settings/device_page/drag_behavior.js
new file mode 100644
index 0000000000000000000000000000000000000000..91d9c502ba8065a01b2810fafa91442d06a10795
--- /dev/null
+++ b/chrome/browser/resources/settings/device_page/drag_behavior.js
@@ -0,0 +1,220 @@
+// Copyright 2016 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.
+
+/**
+ * @fileoverview Behavior for handling dragging elements in a container.
+ * Draggable elements must have the 'draggable' attribute set.
+ */
+
+/**
+ * @typedef {{
+ * x: number,
+ * y: number
+ * }}
+ */
+var DragPosition;
+
+/** @polymerBehavior */
+var DragBehavior = {
+ /**
+ * The id of the element being dragged, or empty if not dragging.
+ * @private {string}
+ */
+ dragId_: '',
+
+ /** @private {boolean} */
+ enabled_: false,
+
+ /** @private {!HTMLDivElement|undefined} */
+ container_: undefined,
+
+ /** @private {?function(string, ?DragPosition):void} */
+ callback_: null,
+
+ /** @private {!DragPosition} */
+ dragStartLocation_: {x: 0, y: 0},
+
+ /**
+ * Used to ignore unnecessary drag events.
+ * @private {?DragPosition}
+ */
+ lastTouchLocation_: null,
+
+ /** @private {?function(!Event)} */
+ mouseDownListener_: null,
+
+ /** @private {?function(!Event)} */
+ mouseMoveListener_: null,
+
+ /** @private {?function(!Event)} */
+ touchStartListener_: null,
+
+ /** @private {?function(!Event)} */
+ touchMoveListener_: null,
+
+ /** @private {?function(!Event)} */
+ endDragListener_: null,
+
+ /**
+ * @param {boolean} enabled
+ * @param {!HTMLDivElement=} opt_container
+ * @param {!function(string, ?DragPosition):void=} opt_callback
+ */
+ initializeDrag: function(enabled, opt_container, opt_callback) {
+ this.enabled_ = enabled;
+ if (!enabled) {
+ if (this.container) {
+ this.container.removeEventListener('mousdown', this.mouseDownListener_);
+ this.mouseDownListener_ = null;
+ this.container.removeEventListener(
+ 'mousemove', this.mouseMoveListener_);
+ this.mouseMoveListener_ = null;
+ this.container.removeEventListener(
+ 'touchstart', this.touchStartListener_);
+ this.touchStartListener_ = null;
+ this.container.removeEventListener(
+ 'touchmove', this.touchMoveListener_);
+ this.touchMoveListener_ = null;
+ this.container.removeEventListener('touchend', this.endDragListener_);
+ }
+ if (this.mouseUpListener_)
+ window.removeEventListener('mouseup', this.endDragListener_);
+ this.endDragListener_ = null;
+ return;
+ }
+
+ if (opt_container !== undefined)
+ this.container_ = opt_container;
+ var container = this.container_;
+ assert(container);
+
+ this.mouseDownListener_ = this.onMouseDown_.bind(this);
+ container.addEventListener('mousedown', this.mouseDownListener_, true);
+
+ this.mouseMoveListener_ = this.onMouseMove_.bind(this);
+ container.addEventListener('mousemove', this.mouseMoveListener_, true);
+
+ this.touchStartListener_ = this.onTouchStart_.bind(this);
+ container.addEventListener('touchstart', this.touchStartListener_, true);
+
+ this.touchMoveListener_ = this.onTouchMove_.bind(this);
+ container.addEventListener('touchmove', this.touchMoveListener_, true);
+
+ this.endDragListener_ = this.endDrag_.bind(this);
+ window.addEventListener('mouseup', this.endDragListener_, true);
+ container.addEventListener('touchend', this.endDragListener_, true);
+
+ if (opt_callback !== undefined)
+ this.callback_ = opt_callback;
+ },
+
+ /**
+ * @param {Event} e The mouse down event.
+ * @return {boolean}
+ * @private
+ */
+ onMouseDown_: function(e) {
+ if (e.button != 0)
+ return true;
+ if (!e.target.getAttribute('draggable'))
+ return true;
+ e.preventDefault();
+ var target = assertInstanceof(e.target, HTMLElement);
+ return this.startDrag_(target, {x: e.pageX, y: e.pageY});
+ },
+
+ /**
+ * @param {Event} e The mouse move event.
+ * @return {boolean}
+ * @private
+ */
+ onMouseMove_: function(e) {
+ e.preventDefault();
+ return this.processDrag_(e, {x: e.pageX, y: e.pageY});
+ },
+
+ /**
+ * @param {Event} e The touch start event.
+ * @return {boolean}
+ * @private
+ */
+ onTouchStart_: function(e) {
+ if (e.touches.length != 1)
+ return false;
+
+ e.preventDefault();
+ var touch = e.touches[0];
+ this.lastTouchLocation_ = {x: touch.pageX, y: touch.pageY};
+ var target = assertInstanceof(e.target, HTMLElement);
+ return this.startDrag_(target, this.lastTouchLocation_);
+ },
+
+ /**
+ * @param {Event} e The touch move event.
+ * @return {boolean}
+ * @private
+ */
+ onTouchMove_: function(e) {
+ if (e.touches.length != 1)
+ return true;
+
+ var touchLocation = {x: e.touches[0].pageX, y: e.touches[0].pageY};
+ // Touch move events can happen even if the touch location doesn't change
+ // and on small unintentional finger movements. Ignore these small changes.
+ if (this.lastTouchLocation_) {
+ /** @const */ var IGNORABLE_TOUCH_MOVE_PX = 1;
+ var xDiff = Math.abs(touchLocation.x - this.lastTouchLocation_.x);
+ var yDiff = Math.abs(touchLocation.y - this.lastTouchLocation_.y);
+ if (xDiff <= IGNORABLE_TOUCH_MOVE_PX && yDiff <= IGNORABLE_TOUCH_MOVE_PX)
+ return true;
+ }
+ this.lastTouchLocation_ = touchLocation;
+ e.preventDefault();
+ return this.processDrag_(e, touchLocation);
+ },
+
+ /**
+ * @param {!HTMLElement} target
+ * @param {!DragPosition} eventLocation
+ * @return {boolean}
+ * @private
+ */
+ startDrag_: function(target, eventLocation) {
+ this.dragId_ = target.id;
+ this.dragStartLocation_ = eventLocation;
+ return false;
+ },
+
+ /**
+ * @param {Event} e
+ * @return {boolean}
+ * @private
+ */
+ endDrag_: function(e) {
+ if (this.dragId_ && this.callback_)
+ this.callback_(this.dragId_, null);
+ this.dragId_ = '';
+ this.lastTouchLocation_ = null;
+ return false;
+ },
+
+ /**
+ * @param {Event} e The event which triggers this drag.
+ * @param {DragPosition} eventLocation The location of the event.
+ * @return {boolean}
+ * @private
+ */
+ processDrag_: function(e, eventLocation) {
+ if (!this.dragId_)
+ return true;
+ if (this.callback_) {
+ var delta = {
+ x: eventLocation.x - this.dragStartLocation_.x,
+ y: eventLocation.y - this.dragStartLocation_.y,
+ };
+ this.callback_(this.dragId_, delta);
+ }
+ return false;
+ },
+};

Powered by Google App Engine
This is Rietveld 408576698