1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)'use strict';
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/**
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * Drag selector used on the file list or the grid table.
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * TODO(hirono): Support drag selection for grid view. crbug.com/224832
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * @constructor
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) */
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)function DragSelector() {
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /**
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * Target list of drag selection.
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * @type {cr.ui.List}
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * @private
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   */
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.target_ = null;
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /**
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * Border element of drag handle.
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * @type {HtmlElement}
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * @private
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   */
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.border_ = null;
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /**
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * Start point of dragging.
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * @type {number?}
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * @private
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   */
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.startX_ = null;
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /**
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * Start point of dragging.
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * @type {number?}
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * @private
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   */
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.startY_ = null;
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /**
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * Indexes of selected items by dragging at the last update.
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * @type {Array.<number>!}
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * @private
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   */
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.lastSelection_ = [];
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /**
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * Indexes of selected items at the start of dragging.
50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * @type {Array.<number>!}
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * @private
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   */
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.originalSelection_ = [];
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Bind handlers to make them removable.
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.onMouseMoveBound_ = this.onMouseMove_.bind(this);
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.onMouseUpBound_ = this.onMouseUp_.bind(this);
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Object.seal(this);
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/**
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * Flag that shows whether the item is included in the selection or not.
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * @enum {number}
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * @private
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) */
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)DragSelector.SelectionFlag_ = {
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  IN_LAST_SELECTION: 1 << 0,
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  IN_CURRENT_SELECTION: 1 << 1
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/**
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) * Obtains the scrolled position in the element of mouse pointer from the mouse
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) * event.
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) *
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) * @param {HTMLElement} element Element that has the scroll bars.
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) * @param {Event} event The mouse event.
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) * @return {object} Scrolled position.
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) */
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)DragSelector.getScrolledPosition = function(element, event) {
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!element.cachedBounds) {
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    element.cachedBounds = element.getBoundingClientRect();
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!element.cachedBounds)
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return null;
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  var rect = element.cachedBounds;
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return {
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    x: event.clientX - rect.left + element.scrollLeft,
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    y: event.clientY - rect.top + element.scrollTop
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)/**
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * Starts drag selection by reacting dragstart event.
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * This function must be called from handlers of dragstart event.
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * @this {DragSelector}
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * @param {cr.ui.List} list List where the drag selection starts.
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * @param {Event} event The dragstart event.
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) */
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)DragSelector.prototype.startDragSelection = function(list, event) {
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Precondition check
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!list.selectionModel_.multiple || this.target_)
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Set the target of the drag selection
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.target_ = list;
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Prevent the default action.
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  event.preventDefault();
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Save the start state.
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  var startPos = DragSelector.getScrolledPosition(list, event);
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!startPos)
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  this.startX_ = startPos.x;
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  this.startY_ = startPos.y;
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  this.lastSelection_ = [];
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  this.originalSelection_ = this.target_.selectionModel_.selectedIndexes;
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Create and add the border element
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!this.border_) {
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    this.border_ = this.target_.ownerDocument.createElement('div');
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    this.border_.className = 'drag-selection-border';
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  this.border_.style.left = this.startX_ + 'px';
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  this.border_.style.top = this.startY_ + 'px';
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  this.border_.style.width = '0';
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  this.border_.style.height = '0';
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  list.appendChild(this.border_);
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // If no modifier key is pressed, clear the original selection.
1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!event.shiftKey && !event.ctrlKey)
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    this.target_.selectionModel_.unselectAll();
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Register event handlers.
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The handlers are bounded at the constructor.
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.target_.ownerDocument.addEventListener(
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      'mousemove', this.onMouseMoveBound_, true);
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.target_.ownerDocument.addEventListener(
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      'mouseup', this.onMouseUpBound_, true);
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/**
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Handles the mousemove event.
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * @private
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * @param {MouseEvent} event The mousemove event.
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) */
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)DragSelector.prototype.onMouseMove_ = function(event) {
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Get the selection bounds.
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  var pos = DragSelector.getScrolledPosition(this.target_, event);
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  var borderBounds = {
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    left: Math.max(Math.min(this.startX_, pos.x), 0),
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    top: Math.max(Math.min(this.startY_, pos.y), 0),
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    right: Math.min(Math.max(this.startX_, pos.x), this.target_.scrollWidth),
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bottom: Math.min(Math.max(this.startY_, pos.y), this.target_.scrollHeight)
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  borderBounds.width = borderBounds.right - borderBounds.left;
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  borderBounds.height = borderBounds.bottom - borderBounds.top;
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Collect items within the selection rect.
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  var currentSelection = this.target_.getHitElements(
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      borderBounds.left,
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      borderBounds.top,
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      borderBounds.width,
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      borderBounds.height);
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  var pointedElements = this.target_.getHitElements(pos.x, pos.y);
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  var leadIndex = pointedElements.length ? pointedElements[0] : -1;
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Diff the selection between currentSelection and this.lastSelection_.
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  var selectionFlag = [];
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (var i = 0; i < this.lastSelection_.length; i++) {
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    var index = this.lastSelection_[i];
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Bit operator can be used for undefined value.
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    selectionFlag[index] =
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        selectionFlag[index] | DragSelector.SelectionFlag_.IN_LAST_SELECTION;
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (var i = 0; i < currentSelection.length; i++) {
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    var index = currentSelection[i];
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Bit operator can be used for undefined value.
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    selectionFlag[index] =
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        selectionFlag[index] | DragSelector.SelectionFlag_.IN_CURRENT_SELECTION;
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Update the selection
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.target_.selectionModel_.beginChange();
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (var name in selectionFlag) {
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    var index = parseInt(name);
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    var flag = selectionFlag[name];
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // The flag may be one of followings:
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // - IN_LAST_SELECTION | IN_CURRENT_SELECTION
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // - IN_LAST_SELECTION
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // - IN_CURRENT_SELECTION
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // - undefined
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // If the flag equals to (IN_LAST_SELECTION | IN_CURRENT_SELECTION),
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // this is included in both the last selection and the current selection.
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // We have nothing to do for this item.
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (flag == DragSelector.SelectionFlag_.IN_LAST_SELECTION) {
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // If the flag equals to IN_LAST_SELECTION,
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // then the item is included in lastSelection but not in currentSelection.
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Revert the selection state to this.originalSelection_.
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      this.target_.selectionModel_.setIndexSelected(
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          index, this.originalSelection_.indexOf(index) != -1);
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (flag == DragSelector.SelectionFlag_.IN_CURRENT_SELECTION) {
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // If the flag equals to IN_CURRENT_SELECTION,
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // this is included in currentSelection but not in lastSelection.
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      this.target_.selectionModel_.setIndexSelected(index, true);
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (leadIndex != -1) {
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    this.target_.selectionModel_.leadIndex = leadIndex;
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    this.target_.selectionModel_.anchorIndex = leadIndex;
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.target_.selectionModel_.endChange();
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.lastSelection_ = currentSelection;
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Update the size of border
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.border_.style.left = borderBounds.left + 'px';
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.border_.style.top = borderBounds.top + 'px';
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.border_.style.width = borderBounds.width + 'px';
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.border_.style.height = borderBounds.height + 'px';
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/**
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * Handle the mouseup event.
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * @private
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * @param {MouseEvent} event The mouseup event.
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) */
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)DragSelector.prototype.onMouseUp_ = function(event) {
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.onMouseMove_(event);
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.target_.removeChild(this.border_);
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.target_.ownerDocument.removeEventListener(
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      'mousemove', this.onMouseMoveBound_, true);
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.target_.ownerDocument.removeEventListener(
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      'mouseup', this.onMouseUpBound_, true);
238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  cr.dispatchSimpleEvent(this.target_, 'dragselectionend');
2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  this.target_.cachedBounds = null;
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  this.target_ = null;
241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // The target may select an item by reacting to the mouseup event.
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // This suppress to the selecting behavior.
243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  event.stopPropagation();
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
245