| // Copyright 2015 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| "use strict"; |
| |
| class CodeView extends View { |
| constructor(divID, PR, sourceText, sourcePosition, broker) { |
| super(divID, broker, null, false); |
| let view = this; |
| view.PR = PR; |
| view.mouseDown = false; |
| view.broker = broker; |
| view.allSpans = []; |
| |
| var selectionHandler = { |
| clear: function() { broker.clear(selectionHandler); }, |
| select: function(items, selected) { |
| var handler = this; |
| var broker = view.broker; |
| for (let span of items) { |
| if (selected) { |
| span.classList.add("selected"); |
| } else { |
| span.classList.remove("selected"); |
| } |
| } |
| var locations = []; |
| for (var span of items) { |
| locations.push({pos_start: span.start, pos_end: span.end}); |
| } |
| broker.clear(selectionHandler); |
| broker.select(selectionHandler, locations, selected); |
| }, |
| selectionDifference: function(span1, inclusive1, span2, inclusive2) { |
| var pos1 = span1.start; |
| var pos2 = span2.start; |
| var result = []; |
| var lineListDiv = view.divNode.firstChild.firstChild.childNodes; |
| for (var i = 0; i < lineListDiv.length; i++) { |
| var currentLineElement = lineListDiv[i]; |
| var spans = currentLineElement.childNodes; |
| for (var j = 0; j < spans.length; ++j) { |
| var currentSpan = spans[j]; |
| if (currentSpan.start > pos1 || |
| (inclusive1 && currentSpan.start == pos1)) { |
| if (currentSpan.start < pos2 || |
| (inclusive2 && currentSpan.start == pos2)) { |
| result.push(currentSpan); |
| } |
| } |
| } |
| } |
| return result; |
| }, |
| brokeredSelect: function(locations, selected) { |
| let firstSelect = view.selection.isEmpty(); |
| for (let location of locations) { |
| let start = location.pos_start; |
| let end = location.pos_end; |
| if (start && end) { |
| let lower = 0; |
| let upper = view.allSpans.length; |
| if (upper > 0) { |
| while ((upper - lower) > 1) { |
| var middle = Math.floor((upper + lower) / 2); |
| var lineStart = view.allSpans[middle].start; |
| if (lineStart < start) { |
| lower = middle; |
| } else if (lineStart > start) { |
| upper = middle; |
| } else { |
| lower = middle; |
| break; |
| } |
| } |
| var currentSpan = view.allSpans[lower]; |
| var currentLineElement = currentSpan.parentNode; |
| if ((currentSpan.start <= start && start < currentSpan.end) || |
| (currentSpan.start <= end && end < currentSpan.end)) { |
| if (firstSelect) { |
| makeContainerPosVisible( |
| view.divNode, currentLineElement.offsetTop); |
| firstSelect = false; |
| } |
| view.selection.select(currentSpan, selected); |
| } |
| } |
| } |
| } |
| }, |
| brokeredClear: function() { view.selection.clear(); }, |
| }; |
| view.selection = new Selection(selectionHandler); |
| broker.addSelectionHandler(selectionHandler); |
| |
| view.handleSpanMouseDown = function(e) { |
| e.stopPropagation(); |
| if (!e.shiftKey) { |
| view.selection.clear(); |
| } |
| view.selection.select(this, true); |
| view.mouseDown = true; |
| } |
| |
| view.handleSpanMouseMove = function(e) { |
| if (view.mouseDown) { |
| view.selection.extendTo(this); |
| } |
| } |
| |
| view.handleCodeMouseDown = function(e) { view.selection.clear(); } |
| |
| document.addEventListener('mouseup', function(e) { |
| view.mouseDown = false; |
| }, false); |
| |
| view.initializeCode(sourceText, sourcePosition); |
| } |
| |
| initializeContent(data, rememberedSelection) { this.data = data; } |
| |
| initializeCode(sourceText, sourcePosition) { |
| var view = this; |
| var codePre = document.createElement("pre"); |
| codePre.classList.add("prettyprint"); |
| view.divNode.innerHTML = ""; |
| view.divNode.appendChild(codePre); |
| if (sourceText != "") { |
| codePre.classList.add("linenums"); |
| codePre.textContent = sourceText; |
| try { |
| // Wrap in try to work when offline. |
| view.PR.prettyPrint(); |
| } catch (e) { |
| } |
| |
| view.divNode.onmousedown = this.handleCodeMouseDown; |
| |
| var base = sourcePosition; |
| var current = 0; |
| var lineListDiv = view.divNode.firstChild.firstChild.childNodes; |
| for (let i = 0; i < lineListDiv.length; i++) { |
| var currentLineElement = lineListDiv[i]; |
| currentLineElement.id = "li" + i; |
| var pos = base + current; |
| currentLineElement.pos = pos; |
| var spans = currentLineElement.childNodes; |
| for (let j = 0; j < spans.length; ++j) { |
| var currentSpan = spans[j]; |
| if (currentSpan.nodeType == 1) { |
| currentSpan.start = pos; |
| currentSpan.end = pos + currentSpan.textContent.length; |
| currentSpan.onmousedown = this.handleSpanMouseDown; |
| currentSpan.onmousemove = this.handleSpanMouseMove; |
| view.allSpans.push(currentSpan); |
| } |
| current += currentSpan.textContent.length; |
| pos = base + current; |
| } |
| while ((current < sourceText.length) && |
| (sourceText[current] == '\n' || sourceText[current] == '\r')) { |
| ++current; |
| } |
| } |
| } |
| } |
| |
| deleteContent() {} |
| } |