d3905561b9
Also convert CodeView to a class and fix a host of selection bugs in the process, as well as move the logic and data to "enrich" location with one type of location data with location data known globally to the whole graph in the selection broker. Review-Url: https://codereview.chromium.org/2230083004 Cr-Commit-Position: refs/heads/master@{#38544}
173 lines
5.6 KiB
JavaScript
173 lines
5.6 KiB
JavaScript
// 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;
|
|
if (sourceText == "") {
|
|
var newHtml = "<pre class=\"prettyprint\"</pre>";
|
|
view.divNode.innerHTML = newHtml;
|
|
} else {
|
|
var newHtml =
|
|
"<pre class=\"prettyprint linenums\">" + sourceText + "</pre>";
|
|
view.divNode.innerHTML = newHtml;
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
view.resizeToParent();
|
|
}
|
|
|
|
deleteContent() {}
|
|
}
|