Home | History | Annotate | Download | only in turbolizer
      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 
      5 "use strict";
      6 
      7 class CodeView extends View {
      8   constructor(divID, PR, sourceText, sourcePosition, broker) {
      9     super(divID, broker, null, false);
     10     let view = this;
     11     view.PR = PR;
     12     view.mouseDown = false;
     13     view.broker = broker;
     14     view.allSpans = [];
     15 
     16     var selectionHandler = {
     17       clear: function() { broker.clear(selectionHandler); },
     18       select: function(items, selected) {
     19         var handler = this;
     20         var broker = view.broker;
     21         for (let span of items) {
     22           if (selected) {
     23             span.classList.add("selected");
     24           } else {
     25             span.classList.remove("selected");
     26           }
     27         }
     28         var locations = [];
     29         for (var span of items) {
     30           locations.push({pos_start: span.start, pos_end: span.end});
     31         }
     32         broker.clear(selectionHandler);
     33         broker.select(selectionHandler, locations, selected);
     34       },
     35       selectionDifference: function(span1, inclusive1, span2, inclusive2) {
     36         var pos1 = span1.start;
     37         var pos2 = span2.start;
     38         var result = [];
     39         var lineListDiv = view.divNode.firstChild.firstChild.childNodes;
     40         for (var i = 0; i < lineListDiv.length; i++) {
     41           var currentLineElement = lineListDiv[i];
     42           var spans = currentLineElement.childNodes;
     43           for (var j = 0; j < spans.length; ++j) {
     44             var currentSpan = spans[j];
     45             if (currentSpan.start > pos1 ||
     46                 (inclusive1 && currentSpan.start == pos1)) {
     47               if (currentSpan.start < pos2 ||
     48                   (inclusive2 && currentSpan.start == pos2)) {
     49                 result.push(currentSpan);
     50               }
     51             }
     52           }
     53         }
     54         return result;
     55       },
     56       brokeredSelect: function(locations, selected) {
     57         let firstSelect = view.selection.isEmpty();
     58         for (let location of locations) {
     59           let start = location.pos_start;
     60           let end = location.pos_end;
     61           if (start && end) {
     62             let lower = 0;
     63             let upper = view.allSpans.length;
     64             if (upper > 0) {
     65               while ((upper - lower) > 1) {
     66                 var middle = Math.floor((upper + lower) / 2);
     67                 var lineStart = view.allSpans[middle].start;
     68                 if (lineStart < start) {
     69                   lower = middle;
     70                 } else if (lineStart > start) {
     71                   upper = middle;
     72                 } else {
     73                   lower = middle;
     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               }
     88             }
     89           }
     90         }
     91       },
     92       brokeredClear: function() { view.selection.clear(); },
     93     };
     94     view.selection = new Selection(selectionHandler);
     95     broker.addSelectionHandler(selectionHandler);
     96 
     97     view.handleSpanMouseDown = function(e) {
     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);
    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;
    164         }
    165       }
    166     }
    167 
    168     view.resizeToParent();
    169   }
    170 
    171   deleteContent() {}
    172 }
    173