OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 var CodeView = function(divID, PR, sourceText, sourcePosition, broker) { | 5 "use strict"; |
6 "use strict"; | |
7 var view = this; | |
8 | 6 |
9 view.divElement = document.getElementById(divID); | 7 class CodeView extends View { |
10 view.broker = broker; | 8 constructor(divID, PR, sourceText, sourcePosition, broker) { |
11 view.codeSelection = null; | 9 super(divID, broker, null, false); |
12 view.allSpans = []; | 10 let view = this; |
| 11 view.PR = PR; |
| 12 view.mouseDown = false; |
| 13 view.broker = broker; |
| 14 view.allSpans = []; |
13 | 15 |
14 var selectionHandler = { | 16 var selectionHandler = { |
15 clear: function() { | 17 clear: function() { broker.clear(selectionHandler); }, |
16 broker.clear(selectionHandler); | 18 select: function(items, selected) { |
17 }, | 19 var handler = this; |
18 select: function(items, selected) { | 20 var broker = view.broker; |
19 var handler = this; | 21 for (let span of items) { |
20 var divElement = view.divElement; | 22 if (selected) { |
21 var broker = view.broker; | 23 span.classList.add("selected"); |
22 for (let span of items) { | 24 } else { |
23 if (selected) { | 25 span.classList.remove("selected"); |
24 span.classList.add("selected"); | 26 } |
25 } else { | |
26 span.classList.remove("selected"); | |
27 } | 27 } |
28 } | 28 var locations = []; |
29 var ranges = []; | 29 for (var span of items) { |
30 for (var span of items) { | 30 locations.push({pos_start: span.start, pos_end: span.end}); |
31 ranges.push([span.start, span.end, null]); | 31 } |
32 } | 32 broker.clear(selectionHandler); |
33 broker.clear(selectionHandler); | 33 broker.select(selectionHandler, locations, selected); |
34 broker.select(selectionHandler, ranges, selected); | 34 }, |
35 }, | 35 selectionDifference: function(span1, inclusive1, span2, inclusive2) { |
36 selectionDifference: function(span1, inclusive1, span2, inclusive2) { | 36 var pos1 = span1.start; |
37 var pos1 = span1.start; | 37 var pos2 = span2.start; |
38 var pos2 = span2.start; | 38 var result = []; |
39 var result = []; | 39 var lineListDiv = view.divNode.firstChild.firstChild.childNodes; |
40 var lineListDiv = view.divElement.firstChild.firstChild.childNodes; | 40 for (var i = 0; i < lineListDiv.length; i++) { |
41 for (var i=0; i < lineListDiv.length; i++) { | 41 var currentLineElement = lineListDiv[i]; |
42 var currentLineElement = lineListDiv[i]; | 42 var spans = currentLineElement.childNodes; |
43 var spans = currentLineElement.childNodes; | 43 for (var j = 0; j < spans.length; ++j) { |
44 for (var j=0; j < spans.length; ++j) { | 44 var currentSpan = spans[j]; |
45 var currentSpan = spans[j]; | 45 if (currentSpan.start > pos1 || |
46 if (currentSpan.start > pos1 || (inclusive1 && currentSpan.start == po
s1)) { | 46 (inclusive1 && currentSpan.start == pos1)) { |
47 if (currentSpan.start < pos2 || (inclusive2 && currentSpan.start ==
pos2)) { | 47 if (currentSpan.start < pos2 || |
48 result.push(currentSpan); | 48 (inclusive2 && currentSpan.start == pos2)) { |
| 49 result.push(currentSpan); |
| 50 } |
49 } | 51 } |
50 } | 52 } |
51 } | 53 } |
52 } | 54 return result; |
53 return result; | 55 }, |
54 }, | 56 brokeredSelect: function(locations, selected) { |
55 brokeredSelect: function(ranges, selected) { | 57 let firstSelect = view.selection.isEmpty(); |
56 var firstSelect = view.codeSelection.isEmpty(); | 58 for (let location of locations) { |
57 for (var range of ranges) { | 59 let start = location.pos_start; |
58 var start = range[0]; | 60 let end = location.pos_end; |
59 var end = range[1]; | 61 if (start && end) { |
60 var lower = 0; | 62 let lower = 0; |
61 var upper = view.allSpans.length; | 63 let upper = view.allSpans.length; |
62 if (upper > 0) { | 64 if (upper > 0) { |
63 while ((upper - lower) > 1) { | 65 while ((upper - lower) > 1) { |
64 var middle = Math.floor((upper + lower) / 2); | 66 var middle = Math.floor((upper + lower) / 2); |
65 var lineStart = view.allSpans[middle].start; | 67 var lineStart = view.allSpans[middle].start; |
66 if (lineStart < start) { | 68 if (lineStart < start) { |
67 lower = middle; | 69 lower = middle; |
68 } else if (lineStart > start) { | 70 } else if (lineStart > start) { |
69 upper = middle; | 71 upper = middle; |
70 } else { | 72 } else { |
71 lower = middle; | 73 lower = middle; |
72 break; | 74 break; |
| 75 } |
| 76 } |
| 77 var currentSpan = view.allSpans[lower]; |
| 78 var currentLineElement = currentSpan.parentNode; |
| 79 if ((currentSpan.start <= start && start < currentSpan.end) || |
| 80 (currentSpan.start <= end && end < currentSpan.end)) { |
| 81 if (firstSelect) { |
| 82 makeContainerPosVisible( |
| 83 view.divNode, currentLineElement.offsetTop); |
| 84 firstSelect = false; |
| 85 } |
| 86 view.selection.select(currentSpan, selected); |
| 87 } |
73 } | 88 } |
74 } | 89 } |
75 var currentSpan = view.allSpans[lower]; | 90 } |
76 var currentLineElement = currentSpan.parentNode; | 91 }, |
77 if ((currentSpan.start <= start && start < currentSpan.end) || | 92 brokeredClear: function() { view.selection.clear(); }, |
78 (currentSpan.start <= end && end < currentSpan.end)) { | 93 }; |
79 if (firstSelect) { | 94 view.selection = new Selection(selectionHandler); |
80 makeContainerPosVisible(view.divElement, currentLineElement.offset
Top); | 95 broker.addSelectionHandler(selectionHandler); |
81 firstSelect = false; | 96 |
82 } | 97 view.handleSpanMouseDown = function(e) { |
83 view.codeSelection.select(currentSpan, selected); | 98 e.stopPropagation(); |
| 99 if (!e.shiftKey) { |
| 100 view.selection.clear(); |
| 101 } |
| 102 view.selection.select(this, true); |
| 103 view.mouseDown = true; |
| 104 } |
| 105 |
| 106 view.handleSpanMouseMove = function(e) { |
| 107 if (view.mouseDown) { |
| 108 view.selection.extendTo(this); |
| 109 } |
| 110 } |
| 111 |
| 112 view.handleCodeMouseDown = function(e) { view.selection.clear(); } |
| 113 |
| 114 document.addEventListener('mouseup', function(e) { |
| 115 view.mouseDown = false; |
| 116 }, false); |
| 117 |
| 118 view.initializeCode(sourceText, sourcePosition); |
| 119 } |
| 120 |
| 121 initializeContent(data, rememberedSelection) { this.data = data; } |
| 122 |
| 123 initializeCode(sourceText, sourcePosition) { |
| 124 var view = this; |
| 125 if (sourceText == "") { |
| 126 var newHtml = "<pre class=\"prettyprint\"</pre>"; |
| 127 view.divNode.innerHTML = newHtml; |
| 128 } else { |
| 129 var newHtml = |
| 130 "<pre class=\"prettyprint linenums\">" + sourceText + "</pre>"; |
| 131 view.divNode.innerHTML = newHtml; |
| 132 try { |
| 133 // Wrap in try to work when offline. |
| 134 view.PR.prettyPrint(); |
| 135 } catch (e) { |
| 136 } |
| 137 |
| 138 view.divNode.onmousedown = this.handleCodeMouseDown; |
| 139 |
| 140 var base = sourcePosition; |
| 141 var current = 0; |
| 142 var lineListDiv = view.divNode.firstChild.firstChild.childNodes; |
| 143 for (let i = 0; i < lineListDiv.length; i++) { |
| 144 var currentLineElement = lineListDiv[i]; |
| 145 currentLineElement.id = "li" + i; |
| 146 var pos = base + current; |
| 147 currentLineElement.pos = pos; |
| 148 var spans = currentLineElement.childNodes; |
| 149 for (let j = 0; j < spans.length; ++j) { |
| 150 var currentSpan = spans[j]; |
| 151 if (currentSpan.nodeType == 1) { |
| 152 currentSpan.start = pos; |
| 153 currentSpan.end = pos + currentSpan.textContent.length; |
| 154 currentSpan.onmousedown = this.handleSpanMouseDown; |
| 155 currentSpan.onmousemove = this.handleSpanMouseMove; |
| 156 view.allSpans.push(currentSpan); |
84 } | 157 } |
| 158 current += currentSpan.textContent.length; |
| 159 pos = base + current; |
| 160 } |
| 161 while ((current < sourceText.length) && |
| 162 (sourceText[current] == '\n' || sourceText[current] == '\r')) { |
| 163 ++current; |
85 } | 164 } |
86 } | 165 } |
87 }, | 166 } |
88 brokeredClear: function() { | |
89 view.codeSelection.clear(); | |
90 }, | |
91 }; | |
92 | 167 |
93 view.codeSelection = new Selection(selectionHandler); | 168 view.resizeToParent(); |
94 broker.addSelectionHandler(selectionHandler); | |
95 | |
96 var mouseDown = false; | |
97 | |
98 this.handleSpanMouseDown = function(e) { | |
99 e.stopPropagation(); | |
100 if (!e.shiftKey) { | |
101 view.codeSelection.clear(); | |
102 } | |
103 view.codeSelection.select(this, true); | |
104 mouseDown = true; | |
105 } | 169 } |
106 | 170 |
107 this.handleSpanMouseMove = function(e) { | 171 deleteContent() {} |
108 if (mouseDown) { | |
109 view.codeSelection.extendTo(this); | |
110 } | |
111 } | |
112 | |
113 this.handleCodeMouseDown = function(e) { | |
114 view.codeSelection.clear(); | |
115 } | |
116 | |
117 document.addEventListener('mouseup', function(e){ | |
118 mouseDown = false; | |
119 }, false); | |
120 | |
121 this.initializeCode(sourceText, sourcePosition); | |
122 } | 172 } |
123 | |
124 CodeView.prototype.initializeCode = function(sourceText, sourcePosition) { | |
125 var view = this; | |
126 if (sourceText == "") { | |
127 var newHtml = "<pre class=\"prettyprint\"</pre>"; | |
128 view.divElement.innerHTML = newHtml; | |
129 } else { | |
130 var newHtml = "<pre class=\"prettyprint linenums\">" | |
131 + sourceText + "</pre>"; | |
132 view.divElement.innerHTML = newHtml; | |
133 try { | |
134 // Wrap in try to work when offline. | |
135 PR.prettyPrint(); | |
136 } catch (e) { | |
137 } | |
138 | |
139 view.divElement.onmousedown = this.handleCodeMouseDown; | |
140 | |
141 var base = sourcePosition; | |
142 var current = 0; | |
143 var lineListDiv = view.divElement.firstChild.firstChild.childNodes; | |
144 for (i=0; i < lineListDiv.length; i++) { | |
145 var currentLineElement = lineListDiv[i]; | |
146 currentLineElement.id = "li" + i; | |
147 var pos = base + current; | |
148 currentLineElement.pos = pos; | |
149 var spans = currentLineElement.childNodes; | |
150 for (j=0; j < spans.length; ++j) { | |
151 var currentSpan = spans[j]; | |
152 if (currentSpan.nodeType == 1) { | |
153 currentSpan.start = pos; | |
154 currentSpan.end = pos + currentSpan.textContent.length; | |
155 currentSpan.onmousedown = this.handleSpanMouseDown; | |
156 currentSpan.onmousemove = this.handleSpanMouseMove; | |
157 view.allSpans.push(currentSpan); | |
158 } | |
159 current += currentSpan.textContent.length; | |
160 pos = base + current; | |
161 } | |
162 while ((current < sourceText.length) && ( | |
163 sourceText[current] == '\n' || | |
164 sourceText[current] == '\r')) { | |
165 ++current; | |
166 } | |
167 } | |
168 } | |
169 | |
170 this.resizeToParent(); | |
171 } | |
172 | |
173 CodeView.prototype.resizeToParent = function() { | |
174 var view = this; | |
175 var documentElement = document.documentElement; | |
176 var y = view.divElement.parentNode.clientHeight || documentElement.clientHeigh
t; | |
177 view.divElement.style.height = y + "px"; | |
178 } | |
OLD | NEW |