1// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5var Selection = function(handler) {
6  this.handler = handler;
7  this.selectionBase = null;
8  this.lastSelection = null;
9  this.selection = new Set();
10}
11
12
13Selection.prototype.isEmpty = function() {
14  return this.selection.size == 0;
15}
16
17
18Selection.prototype.clear = function() {
19  var handler = this.handler;
20  this.selectionBase = null;
21  this.lastSelection = null;
22  handler.select(this.selection, false);
23  handler.clear();
24  this.selection = new Set();
25}
26
27
28count = 0;
29
30Selection.prototype.select = function(s, isSelected) {
31  var handler = this.handler;
32  if (!(Symbol.iterator in Object(s))) { s = [s]; }
33  if (isSelected) {
34    let first = true;
35    for (let i of s) {
36      if (first) {
37        this.selectionBase = i;
38        this.lastSelection = i;
39        first = false;
40      }
41      this.selection.add(i);
42    }
43    handler.select(this.selection, true);
44  } else {
45    let unselectSet = new Set();
46    for (let i of s) {
47      if (this.selection.has(i)) {
48        unselectSet.add(i);
49        this.selection.delete(i);
50      }
51    }
52    handler.select(unselectSet, false);
53  }
54}
55
56
57Selection.prototype.extendTo = function(pos) {
58  if (pos == this.lastSelection || this.lastSelection === null) return;
59
60  var handler = this.handler;
61  var pos_diff = handler.selectionDifference(pos, true, this.lastSelection, false);
62  var unselect_diff = [];
63  if (pos_diff.length == 0) {
64    pos_diff = handler.selectionDifference(this.selectionBase, false, pos, true);
65    if (pos_diff.length != 0) {
66      unselect_diff = handler.selectionDifference(this.lastSelection, true, this.selectionBase, false);
67      this.selection = new Set();
68      this.selection.add(this.selectionBase);
69      for (var d of pos_diff) {
70        this.selection.add(d);
71      }
72    } else {
73      unselect_diff = handler.selectionDifference(this.lastSelection, true, pos, false);
74      for (var d of unselect_diff) {
75        this.selection.delete(d);
76      }
77    }
78  } else {
79    unselect_diff = handler.selectionDifference(this.selectionBase, false, this.lastSelection, true);
80    if (unselect_diff != 0) {
81      pos_diff = handler.selectionDifference(pos, true, this.selectionBase, false);
82      if (pos_diff.length == 0) {
83        unselect_diff = handler.selectionDifference(pos, false, this.lastSelection, true);
84      }
85      for (var d of unselect_diff) {
86        this.selection.delete(d);
87      }
88    }
89    if (pos_diff.length != 0) {
90      for (var d of pos_diff) {
91        this.selection.add(d);
92      }
93    }
94  }
95  handler.select(unselect_diff, false);
96  handler.select(pos_diff, true);
97  this.lastSelection = pos;
98}
99
100
101Selection.prototype.detachSelection = function() {
102  var result = new Set();
103  for (var i of this.selection) {
104    result.add(i);
105  }
106  this.clear();
107  return result;
108}
109