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  } else {
44    let unselectSet = new Set();
45    for (let i of s) {
46      if (this.selection.has(i)) {
47        unselectSet.add(i);
48        this.selection.delete(i);
49      }
50    }
51  }
52  handler.select(this.selection, isSelected);
53}
54
55
56Selection.prototype.extendTo = function(pos) {
57  if (pos == this.lastSelection || this.lastSelection === null) return;
58
59  var handler = this.handler;
60  var pos_diff = handler.selectionDifference(pos, true, this.lastSelection, false);
61  var unselect_diff = [];
62  if (pos_diff.length == 0) {
63    pos_diff = handler.selectionDifference(this.selectionBase, false, pos, true);
64    if (pos_diff.length != 0) {
65      unselect_diff = handler.selectionDifference(this.lastSelection, true, this.selectionBase, false);
66      this.selection = new Set();
67      this.selection.add(this.selectionBase);
68      for (var d of pos_diff) {
69        this.selection.add(d);
70      }
71    } else {
72      unselect_diff = handler.selectionDifference(this.lastSelection, true, pos, false);
73      for (var d of unselect_diff) {
74        this.selection.delete(d);
75      }
76    }
77  } else {
78    unselect_diff = handler.selectionDifference(this.selectionBase, false, this.lastSelection, true);
79    if (unselect_diff != 0) {
80      pos_diff = handler.selectionDifference(pos, true, this.selectionBase, false);
81      if (pos_diff.length == 0) {
82        unselect_diff = handler.selectionDifference(pos, false, this.lastSelection, true);
83      }
84      for (var d of unselect_diff) {
85        this.selection.delete(d);
86      }
87    }
88    if (pos_diff.length != 0) {
89      for (var d of pos_diff) {
90        this.selection.add(d);
91      }
92    }
93  }
94  handler.select(unselect_diff, false);
95  handler.select(pos_diff, true);
96  this.lastSelection = pos;
97}
98
99
100Selection.prototype.detachSelection = function() {
101  var result = new Set();
102  for (var i of this.selection) {
103    result.add(i);
104  }
105  this.clear();
106  return result;
107}
108