| 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 |