home *** CD-ROM | disk | FTP | other *** search
/ Computer Active Guide 2009 July / CAG7.ISO / Internetas / SafariSetup.exe / AppleApplicationSupport.msi / WebKit.resources_inspector_TextEditorHighlighter.js < prev    next >
Encoding:
Text File  |  2010-06-03  |  5.5 KB  |  133 lines

  1. /*
  2.  * Copyright (C) 2009 Google Inc. All rights reserved.
  3.  * Copyright (C) 2009 Apple Inc. All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions are
  7.  * met:
  8.  *
  9.  *     * Redistributions of source code must retain the above copyright
  10.  * notice, this list of conditions and the following disclaimer.
  11.  *     * Redistributions in binary form must reproduce the above
  12.  * copyright notice, this list of conditions and the following disclaimer
  13.  * in the documentation and/or other materials provided with the
  14.  * distribution.
  15.  *     * Neither the name of Google Inc. nor the names of its
  16.  * contributors may be used to endorse or promote products derived from
  17.  * this software without specific prior written permission.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23.  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30.  */
  31.  
  32. WebInspector.TextEditorHighlighter = function(textModel, damageCallback)
  33. {
  34.     this._textModel = textModel;
  35.     this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/html");
  36.     this._damageCallback = damageCallback;
  37.     this.reset();
  38. }
  39.  
  40. WebInspector.TextEditorHighlighter.prototype = {
  41.     set mimeType(mimeType)
  42.     {
  43.         var tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType);
  44.         if (tokenizer) {
  45.             this._tokenizer = tokenizer;
  46.             this._tokenizerCondition = this._tokenizer.initialCondition;
  47.         }
  48.     },
  49.  
  50.     reset: function()
  51.     {
  52.         this._lastHighlightedLine = 0;
  53.         this._lastHighlightedColumn = 0;
  54.         this._tokenizerCondition = this._tokenizer.initialCondition;
  55.     },
  56.  
  57.     highlight: function(endLine)
  58.     {
  59.         // First check if we have work to do.
  60.         if (endLine <= this._lastHighlightedLine)
  61.             return;
  62.  
  63.         this._requestedEndLine = endLine;
  64.  
  65.         if (this._highlightTimer) {
  66.             // There is a timer scheduled, it will catch the new job based on the new endLine set.
  67.             return;
  68.         }
  69.  
  70.         // Do small highlight synchronously. This will provide instant highlight on PageUp / PageDown, gentle scrolling.
  71.         this._highlightInChunks(endLine);
  72.  
  73.         // Schedule tail highlight if necessary.
  74.         if (this._lastHighlightedLine < endLine)
  75.             this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, endLine), 100);
  76.     },
  77.  
  78.     _highlightInChunks: function(endLine)
  79.     {
  80.         delete this._highlightTimer;
  81.  
  82.         // First we always check if we have work to do. Could be that user scrolled back and we can quit.
  83.         if (this._requestedEndLine <= this._lastHighlightedLine)
  84.             return;
  85.  
  86.         if (this._requestedEndLine !== endLine) {
  87.             // User keeps updating the job in between of our timer ticks. Just reschedule self, don't eat CPU (they must be scrolling).
  88.             this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._requestedEndLine), 100);
  89.             return;
  90.         }
  91.  
  92.         this._highlightLines(this._requestedEndLine);
  93.  
  94.         // Schedule tail highlight if necessary.
  95.         if (this._lastHighlightedLine < this._requestedEndLine)
  96.             this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._requestedEndLine), 10);
  97.     },
  98.  
  99.     _highlightLines: function(endLine)
  100.     {
  101.         // Tokenizer is stateless and reused accross viewers, restore its condition before highlight and save it after.
  102.         this._tokenizer.condition = this._tokenizerCondition;
  103.         var tokensCount = 0;
  104.         for (var lineNumber = this._lastHighlightedLine; lineNumber < endLine; ++lineNumber) {
  105.             var line = this._textModel.line(lineNumber);
  106.             this._tokenizer.line = line;
  107.             var attributes = this._textModel.getAttribute(lineNumber, "highlight") || {};
  108.  
  109.             // Highlight line.
  110.             do {
  111.                 var newColumn = this._tokenizer.nextToken(this._lastHighlightedColumn);
  112.                 var tokenType = this._tokenizer.tokenType;
  113.                 if (tokenType)
  114.                     attributes[this._lastHighlightedColumn] = { length: newColumn - this._lastHighlightedColumn, tokenType: tokenType, subTokenizer: this._tokenizer.subTokenizer };
  115.                 this._lastHighlightedColumn = newColumn;
  116.                 if (++tokensCount > 1000)
  117.                     break;
  118.             } while (this._lastHighlightedColumn < line.length)
  119.  
  120.             this._textModel.setAttribute(lineNumber, "highlight", attributes);
  121.             if (this._lastHighlightedColumn < line.length) {
  122.                 // Too much work for single chunk - exit.
  123.                 break;
  124.             } else
  125.                 this._lastHighlightedColumn = 0;
  126.         }
  127.  
  128.         this._damageCallback(this._lastHighlightedLine, lineNumber);
  129.         this._tokenizerCondition = this._tokenizer.condition;
  130.         this._lastHighlightedLine = lineNumber;
  131.     }
  132. }
  133.