Changeset 49071 in webkit


Ignore:
Timestamp:
Oct 3, 2009 7:50:05 PM (15 years ago)
Author:
Joseph Pecoraro
Message:

2009-10-03 Joseph Pecoraro <Joseph Pecoraro>

Reviewed by Timothy Hatcher.

CSS Source View Should be Syntax Highlighted
https://bugs.webkit.org/show_bug.cgi?id=14359

Trigger the Syntax Highlighter for CSS files.

  • inspector/front-end/SourceFrame.js: (WebInspector.SourceFrame.prototype.syntaxHighlightJavascript): (WebInspector.SourceFrame.prototype.syntaxHighlightCSS):
  • inspector/front-end/SourceView.js: (WebInspector.SourceView.prototype._contentLoaded):

Factored out the Syntax Highlighting procedure into a "Class"
Added CSSSourceSyntaxHighlighter and JavaScriptSourceSyntaxHighlighter

(WebInspector.SourceSyntaxHighligher):
(WebInspector.SourceSyntaxHighligher.prototype.createSpan):
(WebInspector.SourceSyntaxHighligher.prototype.process.processChunk):
(WebInspector.SourceSyntaxHighligher.prototype.process):
(WebInspector.CSSSourceSyntaxHighligher): the CSS Highlighter
(WebInspector.JavaScriptSourceSyntaxHighligher): the JS Highlighter

Location:
trunk/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r49067 r49071  
     12009-10-03  Joseph Pecoraro  <joepeck@webkit.org>
     2
     3        Reviewed by Timothy Hatcher.
     4
     5        CSS Source View Should be Syntax Highlighted
     6        https://bugs.webkit.org/show_bug.cgi?id=14359
     7
     8          Trigger the Syntax Highlighter for CSS files.
     9
     10        * inspector/front-end/SourceFrame.js:
     11        (WebInspector.SourceFrame.prototype.syntaxHighlightJavascript):
     12        (WebInspector.SourceFrame.prototype.syntaxHighlightCSS):
     13        * inspector/front-end/SourceView.js:
     14        (WebInspector.SourceView.prototype._contentLoaded):
     15
     16          Factored out the Syntax Highlighting procedure into a "Class"
     17          Added CSSSourceSyntaxHighlighter and JavaScriptSourceSyntaxHighlighter
     18
     19        (WebInspector.SourceSyntaxHighligher):
     20        (WebInspector.SourceSyntaxHighligher.prototype.createSpan):
     21        (WebInspector.SourceSyntaxHighligher.prototype.process.processChunk):
     22        (WebInspector.SourceSyntaxHighligher.prototype.process):
     23        (WebInspector.CSSSourceSyntaxHighligher): the CSS Highlighter
     24        (WebInspector.JavaScriptSourceSyntaxHighligher): the JS Highlighter
     25
    1262009-10-03  Adam Barth  <abarth@webkit.org>
    227
  • trunk/WebCore/inspector/front-end/SourceFrame.js

    r48392 r49071  
    246246        styleText += ".webkit-javascript-string, .webkit-javascript-regexp { color: rgb(196, 26, 22); }\n";
    247247
     248        styleText += ".webkit-css-comment { color: rgb(0, 116, 0); }\n";
     249        styleText += ".webkit-css-string, .webkit-css-keyword, .webkit-css-unit { color: rgb(7, 144, 154); }\n";
     250        styleText += ".webkit-css-number { color: rgb(50, 0, 255); }\n";
     251        styleText += ".webkit-css-property, .webkit-css-at-rule { color: rgb(200, 0, 0); }\n";
     252        styleText += ".webkit-css-url { color: rgb(0, 0, 0); }\n";
     253        styleText += ".webkit-css-selector { color: rgb(0, 0, 0); }\n";
     254        styleText += ".webkit-css-pseudo-class { color: rgb(128, 128, 128); }\n";
     255
    248256        // TODO: Move these styles into inspector.css once https://bugs.webkit.org/show_bug.cgi?id=28913 is fixed and popup moved into the top frame.
    249257        styleText += ".popup-content { position: absolute; z-index: 10000; padding: 4px; background-color: rgb(203, 226, 255); -webkit-border-radius: 7px; border: 2px solid rgb(169, 172, 203); }";
     
    254262        // This class is already in inspector.css
    255263        styleText += ".hidden { display: none !important; }";
    256        
     264
    257265        styleElement.textContent = styleText;
    258266
     
    312320        if (!sourceRow._breakpointObject && this.addBreakpointDelegate)
    313321            this.addBreakpointDelegate(this.lineNumberForSourceRow(sourceRow));
    314        
     322
    315323        var breakpoint = sourceRow._breakpointObject;
    316324        if (!breakpoint)
    317325            return;
    318        
     326
    319327        this._editBreakpointCondition(event.target, sourceRow, breakpoint);
    320328        event.preventDefault();
     
    341349        var popupDocument = this.element.contentDocument;
    342350        this._showBreakpointConditionPopup(eventTarget, breakpoint.line, popupDocument);
    343        
     351
    344352        function committed(element, newText)
    345353        {
     
    360368        var dismissedHandler = dismissed.bind(this);
    361369        this._conditionEditorElement.addEventListener("blur", dismissedHandler, false);
    362        
     370
    363371        WebInspector.startEditing(this._conditionEditorElement, committed.bind(this), dismissedHandler);
    364372        this._conditionEditorElement.value = breakpoint.condition;
     
    717725            return;
    718726
    719         function deleteContinueFlags(cell)
    720         {
    721             if (!cell)
    722                 return;
    723             delete cell._commentContinues;
    724             delete cell._singleQuoteStringContinues;
    725             delete cell._doubleQuoteStringContinues;
    726             delete cell._regexpContinues;
    727         }
    728 
    729         function createSpan(content, className)
    730         {
    731             var span = document.createElement("span");
    732             span.className = className;
    733             span.appendChild(document.createTextNode(content));
    734             return span;
    735         }
    736 
    737         function generateFinder(regex, matchNumber, className)
    738         {
    739             return function(str) {
    740                 var match = regex.exec(str);
    741                 if (!match)
    742                     return null;
    743                 previousMatchLength = match[matchNumber].length;
    744                 return createSpan(match[matchNumber], className);
    745             };
    746         }
    747 
    748         var findNumber = generateFinder(/^(-?(\d+\.?\d*([eE][+-]\d+)?|0[xX]\h+|Infinity)|NaN)(?:\W|$)/, 1, "webkit-javascript-number");
    749         var findKeyword = generateFinder(/^(null|true|false|break|case|catch|const|default|finally|for|instanceof|new|var|continue|function|return|void|delete|if|this|do|while|else|in|switch|throw|try|typeof|with|debugger|class|enum|export|extends|import|super|get|set)(?:\W|$)/, 1, "webkit-javascript-keyword");
    750         var findSingleLineString = generateFinder(/^"(?:[^"\\]|\\.)*"|^'([^'\\]|\\.)*'/, 0, "webkit-javascript-string"); // " this quote keeps Xcode happy
    751         var findMultilineCommentStart = generateFinder(/^\/\*.*$/, 0, "webkit-javascript-comment");
    752         var findMultilineCommentEnd = generateFinder(/^.*?\*\//, 0, "webkit-javascript-comment");
    753         var findMultilineSingleQuoteStringStart = generateFinder(/^'(?:[^'\\]|\\.)*\\$/, 0, "webkit-javascript-string");
    754         var findMultilineSingleQuoteStringEnd = generateFinder(/^(?:[^'\\]|\\.)*?'/, 0, "webkit-javascript-string");
    755         var findMultilineDoubleQuoteStringStart = generateFinder(/^"(?:[^"\\]|\\.)*\\$/, 0, "webkit-javascript-string");
    756         var findMultilineDoubleQuoteStringEnd = generateFinder(/^(?:[^"\\]|\\.)*?"/, 0, "webkit-javascript-string");
    757         var findMultilineRegExpEnd = generateFinder(/^(?:[^\/\\]|\\.)*?\/([gim]{0,3})/, 0, "webkit-javascript-regexp");
    758         var findSingleLineComment = generateFinder(/^\/\/.*|^\/\*.*?\*\//, 0, "webkit-javascript-comment");
    759 
    760         function findMultilineRegExpStart(str)
    761         {
    762             var match = /^\/(?:[^\/\\]|\\.)*\\$/.exec(str);
    763             if (!match || !/\\|\$|\.[\?\*\+]|[^\|]\|[^\|]/.test(match[0]))
     727        var jsSyntaxHighlighter = new WebInspector.JavaScriptSourceSyntaxHighlighter(table, this);
     728        jsSyntaxHighlighter.process();
     729    },
     730
     731    syntaxHighlightCSS: function()
     732    {
     733        var table = this.element.contentDocument.getElementsByTagName("table")[0];
     734        if (!table)
     735            return;
     736
     737        var cssSyntaxHighlighter = new WebInspector.CSSSourceSyntaxHighligher(table, this);
     738        cssSyntaxHighlighter.process();
     739    }
     740}
     741
     742WebInspector.SourceFrame.prototype.__proto__ = WebInspector.Object.prototype;
     743
     744WebInspector.SourceSyntaxHighligher = function(table, sourceFrame)
     745{
     746    this.table = table;
     747    this.sourceFrame = sourceFrame;
     748}
     749
     750WebInspector.SourceSyntaxHighligher.prototype = {
     751    createSpan: function(content, className)
     752    {
     753        var span = document.createElement("span");
     754        span.className = className;
     755        span.appendChild(document.createTextNode(content));
     756        return span;
     757    },
     758
     759    generateFinder: function(regex, matchNumber, className)
     760    {
     761        return function(str) {
     762            var match = regex.exec(str);
     763            if (!match)
    764764                return null;
    765             var node = createSpan(match[0], "webkit-javascript-regexp");
    766             previousMatchLength = match[0].length;
    767             return node;
    768         }
    769 
    770         function findSingleLineRegExp(str)
    771         {
    772             var match = /^(\/(?:[^\/\\]|\\.)*\/([gim]{0,3}))(.?)/.exec(str);
    773             if (!match || !(match[2].length > 0 || /\\|\$|\.[\?\*\+]|[^\|]\|[^\|]/.test(match[1]) || /\.|;|,/.test(match[3])))
    774                 return null;
    775             var node = createSpan(match[1], "webkit-javascript-regexp");
    776             previousMatchLength = match[1].length;
    777             return node;
    778         }
    779 
    780         function syntaxHighlightJavascriptLine(line, prevLine)
    781         {
    782             var messageBubble = line.lastChild;
    783             if (messageBubble && messageBubble.nodeType === Node.ELEMENT_NODE && messageBubble.hasStyleClass("webkit-html-message-bubble"))
    784                 line.removeChild(messageBubble);
    785             else
    786                 messageBubble = null;
    787 
    788             var code = line.textContent;
    789 
    790             while (line.firstChild)
    791                 line.removeChild(line.firstChild);
    792 
    793             var token;
    794             var tmp = 0;
    795             var i = 0;
    796             previousMatchLength = 0;
    797 
    798             if (prevLine) {
    799                 if (prevLine._commentContinues) {
    800                     if (!(token = findMultilineCommentEnd(code))) {
    801                         token = createSpan(code, "webkit-javascript-comment");
    802                         line._commentContinues = true;
    803                     }
    804                 } else if (prevLine._singleQuoteStringContinues) {
    805                     if (!(token = findMultilineSingleQuoteStringEnd(code))) {
    806                         token = createSpan(code, "webkit-javascript-string");
    807                         line._singleQuoteStringContinues = true;
    808                     }
    809                 } else if (prevLine._doubleQuoteStringContinues) {
    810                     if (!(token = findMultilineDoubleQuoteStringEnd(code))) {
    811                         token = createSpan(code, "webkit-javascript-string");
    812                         line._doubleQuoteStringContinues = true;
    813                     }
    814                 } else if (prevLine._regexpContinues) {
    815                     if (!(token = findMultilineRegExpEnd(code))) {
    816                         token = createSpan(code, "webkit-javascript-regexp");
    817                         line._regexpContinues = true;
    818                     }
    819                 }
    820                 if (token) {
    821                     i += previousMatchLength ? previousMatchLength : code.length;
    822                     tmp = i;
    823                     line.appendChild(token);
    824                 }
    825             }
    826 
    827             for ( ; i < code.length; ++i) {
    828                 var codeFragment = code.substr(i);
    829                 var prevChar = code[i - 1];
    830                 token = findSingleLineComment(codeFragment);
    831                 if (!token) {
    832                     if ((token = findMultilineCommentStart(codeFragment)))
    833                         line._commentContinues = true;
    834                     else if (!prevChar || /^\W/.test(prevChar)) {
    835                         token = findNumber(codeFragment, code[i - 1]) ||
    836                                 findKeyword(codeFragment, code[i - 1]) ||
    837                                 findSingleLineString(codeFragment) ||
    838                                 findSingleLineRegExp(codeFragment);
    839                         if (!token) {
    840                             if (token = findMultilineSingleQuoteStringStart(codeFragment))
    841                                 line._singleQuoteStringContinues = true;
    842                             else if (token = findMultilineDoubleQuoteStringStart(codeFragment))
    843                                 line._doubleQuoteStringContinues = true;
    844                             else if (token = findMultilineRegExpStart(codeFragment))
    845                                 line._regexpContinues = true;
    846                         }
    847                     }
    848                 }
    849 
    850                 if (token) {
    851                     if (tmp !== i)
    852                         line.appendChild(document.createTextNode(code.substring(tmp, i)));
    853                     line.appendChild(token);
    854                     i += previousMatchLength - 1;
    855                     tmp = i + 1;
    856                 }
    857             }
    858 
    859             if (tmp < code.length)
    860                 line.appendChild(document.createTextNode(code.substring(tmp, i)));
    861 
    862             if (messageBubble)
    863                 line.appendChild(messageBubble);
    864         }
     765            this.previousMatchLength = match[matchNumber].length;
     766            return this.createSpan(match[matchNumber], className);
     767        };
     768    },
     769
     770    process: function()
     771    {
     772        // Split up the work into chunks so we don't block the
     773        // UI thread while processing.
    865774
    866775        var i = 0;
    867         var rows = table.rows;
     776        var rows = this.table.rows;
    868777        var rowsLength = rows.length;
    869778        var previousCell = null;
    870         var previousMatchLength = 0;
    871         var sourceFrame = this;
    872 
    873         // Split up the work into chunks so we don't block the
    874         // UI thread while processing.
     779        const linesPerChunk = 10;
    875780
    876781        function processChunk()
    877782        {
    878             for (var end = Math.min(i + 10, rowsLength); i < end; ++i) {
     783            for (var end = Math.min(i + linesPerChunk, rowsLength); i < end; ++i) {
    879784                var row = rows[i];
    880785                if (!row)
     
    883788                if (!cell)
    884789                    continue;
    885                 syntaxHighlightJavascriptLine(cell, previousCell);
     790                this.syntaxHighlightLine(cell, previousCell);
    886791                if (i < (end - 1))
    887                     deleteContinueFlags(previousCell);
     792                    this.deleteContinueFlags(previousCell);
    888793                previousCell = cell;
    889794            }
    890795
    891796            if (i >= rowsLength && processChunkInterval) {
    892                 deleteContinueFlags(previousCell);
     797                this.deleteContinueFlags(previousCell);
     798                delete this.previousMatchLength;
    893799                clearInterval(processChunkInterval);
    894800
    895                 sourceFrame.dispatchEventToListeners("syntax highlighting complete");
     801                this.sourceFrame.dispatchEventToListeners("syntax highlighting complete");
    896802            }
    897803        }
    898804
    899         processChunk();
    900 
    901         var processChunkInterval = setInterval(processChunk, 25);
     805        var boundProcessChunk = processChunk.bind(this);
     806        var processChunkInterval = setInterval(boundProcessChunk, 25);
     807        boundProcessChunk();
    902808    }
    903809}
    904810
    905 WebInspector.SourceFrame.prototype.__proto__ = WebInspector.Object.prototype;
    906 
     811WebInspector.CSSSourceSyntaxHighligher = function(table, sourceFrame) {
     812    WebInspector.SourceSyntaxHighligher.call(this, table, sourceFrame);
     813
     814    this.findNumber = this.generateFinder(/^((-?(\d+|\d*\.\d+))|^(#[a-fA-F0-9]{3,6}))(?:\D|$)/, 1, "webkit-css-number");
     815    this.findUnits = this.generateFinder(/^(px|em|pt|in|cm|mm|pc|ex)(?:\W|$)/, 1, "webkit-css-unit");
     816    this.findKeyword = this.generateFinder(/^(rgba?|hsla?)(?:\W|$)/, 1, "webkit-css-keyword");
     817    this.findSingleLineString = this.generateFinder(/^"(?:[^"\\]|\\.)*"|^'([^'\\]|\\.)*'/, 0, "webkit-css-string"); // " this quote keeps Xcode happy
     818    this.findSingleLineComment = this.generateFinder(/^\/\*.*?\*\//, 0, "webkit-css-comment");
     819    this.findMultilineCommentStart = this.generateFinder(/^\/\*.*$/, 0, "webkit-css-comment");
     820    this.findMultilineCommentEnd = this.generateFinder(/^.*?\*\//, 0, "webkit-css-comment");
     821    this.findSelector = this.generateFinder(/^([#\.]?[_a-zA-Z].*?)(?:\W|$)/, 1, "webkit-css-selector");
     822    this.findProperty = this.generateFinder(/^(-?[_a-z0-9][_a-z0-9-]*\s*)(?:\:)/, 1, "webkit-css-property");
     823    this.findGenericIdent = this.generateFinder(/^([@-]?[_a-z0-9][_a-z0-9-]*)(?:\W|$)/, 1, "webkit-css-string");
     824}
     825
     826WebInspector.CSSSourceSyntaxHighligher.prototype = {
     827    deleteContinueFlags: function(cell)
     828    {
     829        if (!cell)
     830            return;
     831        delete cell._commentContinues;
     832        delete cell._inSelector;
     833    },
     834
     835    findPseudoClass: function(str)
     836    {
     837        var match = /^(::?)([_a-z0-9][_a-z0-9-]*)/.exec(str);
     838        if (!match)
     839            return null;
     840        this.previousMatchLength = match[0].length;
     841        var span = document.createElement("span");
     842        span.appendChild(document.createTextNode(match[1]));
     843        span.appendChild(this.createSpan(match[2], "webkit-css-pseudo-class"));
     844        return span;
     845    },
     846
     847    findURL: function(str)
     848    {
     849        var match = /^(?:local|url)\(([^\)]*?)\)/.exec(str);
     850        if (!match)
     851            return null;
     852        this.previousMatchLength = match[0].length;
     853        var innerUrlSpan = this.createSpan(match[1], "webkit-css-url");
     854        var outerSpan = document.createElement("span");
     855        outerSpan.appendChild(this.createSpan("url", "webkit-css-keyword"));
     856        outerSpan.appendChild(document.createTextNode("("));
     857        outerSpan.appendChild(innerUrlSpan);
     858        outerSpan.appendChild(document.createTextNode(")"));
     859        return outerSpan;
     860    },
     861
     862    findAtRule: function(str)
     863    {
     864        var match = /^@[_a-z0-9][_a-z0-9-]*(?:\W|$)/.exec(str);
     865        if (!match)
     866            return null;
     867        this.previousMatchLength = match[0].length;
     868        return this.createSpan(match[0], "webkit-css-at-rule");
     869    },
     870
     871    syntaxHighlightLine: function(line, prevLine)
     872    {
     873        var code = line.textContent;
     874        while (line.firstChild)
     875            line.removeChild(line.firstChild);
     876
     877        var token;
     878        var tmp = 0;
     879        var i = 0;
     880        this.previousMatchLength = 0;
     881
     882        if (prevLine) {
     883            if (prevLine._commentContinues) {
     884                if (!(token = this.findMultilineCommentEnd(code))) {
     885                    token = this.createSpan(code, "webkit-javascript-comment");
     886                    line._commentContinues = true;
     887                }
     888            }
     889            if (token) {
     890                i += this.previousMatchLength ? this.previousMatchLength : code.length;
     891                tmp = i;
     892                line.appendChild(token);
     893            }
     894        }
     895
     896        var inSelector = (prevLine && prevLine._inSelector); // inside a selector, we can now parse properties and values
     897        var inAtRuleBlock = (prevLine && prevLine._inAtRuleBlock); // inside an @rule block, but not necessarily inside a selector yet
     898        var atRuleStarted = (prevLine && prevLine._atRuleStarted); // we received an @rule, we may stop the @rule at a semicolon or open a block and become inAtRuleBlock
     899        var atRuleIsSelector = (prevLine && prevLine._atRuleIsSelector); // when this @rule opens a block it immediately goes into parsing properties and values instead of selectors
     900
     901        for ( ; i < code.length; ++i) {
     902            var codeFragment = code.substr(i);
     903            var prevChar = code[i - 1];
     904            var currChar = codeFragment[0];
     905            token = this.findSingleLineComment(codeFragment);
     906            if (!token) {
     907                if ((token = this.findMultilineCommentStart(codeFragment)))
     908                    line._commentContinues = true;
     909                else if (currChar === ";" && !inAtRuleBlock)
     910                    atRuleStarted = false;
     911                else if (currChar === "}") {
     912                    if (inSelector && inAtRuleBlock && atRuleIsSelector) {
     913                        inSelector = false;
     914                        inAtRuleBlock = false;
     915                        atRuleStarted = false;
     916                    } else if (inSelector) {
     917                        inSelector = false;
     918                    } else if (inAtRuleBlock) {
     919                        inAtRuleBlock = false;
     920                        atRuleStarted = false;
     921                    }
     922                } else if (currChar === "{") {
     923                    if (!atRuleStarted || inAtRuleBlock) {
     924                        inSelector = true;
     925                    } else if (!inAtRuleBlock && atRuleIsSelector) {
     926                        inAtRuleBlock = true;
     927                        inSelector = true;
     928                    } else if (!inAtRuleBlock) {
     929                        inAtRuleBlock = true;
     930                        inSelector = false;
     931                    }
     932                } else if (inSelector) {
     933                    if (!prevChar || /^\d/.test(prevChar)) {
     934                        token = this.findUnits(codeFragment);
     935                    } else if (!prevChar || /^\W/.test(prevChar)) {
     936                        token = this.findNumber(codeFragment) ||
     937                                this.findKeyword(codeFragment) ||
     938                                this.findURL(codeFragment) ||
     939                                this.findProperty(codeFragment) ||
     940                                this.findAtRule(codeFragment) ||
     941                                this.findGenericIdent(codeFragment) ||
     942                                this.findSingleLineString(codeFragment);
     943                    }
     944                } else if (!inSelector) {
     945                    if (atRuleStarted && !inAtRuleBlock)
     946                        token = this.findURL(codeFragment); // for @import
     947                    if (!token) {
     948                        token = this.findSelector(codeFragment) ||
     949                                this.findPseudoClass(codeFragment) ||
     950                                this.findAtRule(codeFragment);
     951                    }
     952                }
     953            }
     954
     955            if (token) {
     956                if (currChar === '@') {
     957                    atRuleStarted = true;
     958
     959                    // The @font-face at-rule does not contain selectors like other at-rules
     960                    // instead it acts as a selector and contains properties and values.
     961                    atRuleIsSelector = /font-face/.test(token.textContent);
     962                }
     963
     964                if (tmp !== i)
     965                    line.appendChild(document.createTextNode(code.substring(tmp, i)));
     966                line.appendChild(token);
     967                i += this.previousMatchLength - 1;
     968                tmp = i + 1;
     969            }
     970        }
     971
     972        line._inSelector = inSelector;
     973        line._inAtRuleBlock = inAtRuleBlock;
     974        line._atRuleStarted = atRuleStarted;
     975        line._atRuleIsSelector = atRuleIsSelector;
     976
     977        if (tmp < code.length)
     978            line.appendChild(document.createTextNode(code.substring(tmp, i)));
     979    }
     980}
     981
     982WebInspector.CSSSourceSyntaxHighligher.prototype.__proto__ = WebInspector.SourceSyntaxHighligher.prototype;
     983
     984WebInspector.JavaScriptSourceSyntaxHighlighter = function(table, sourceFrame) {
     985    WebInspector.SourceSyntaxHighligher.call(this, table, sourceFrame);
     986
     987    this.findNumber = this.generateFinder(/^(-?(\d+\.?\d*([eE][+-]\d+)?|0[xX]\h+|Infinity)|NaN)(?:\W|$)/, 1, "webkit-javascript-number");
     988    this.findKeyword = this.generateFinder(/^(null|true|false|break|case|catch|const|default|finally|for|instanceof|new|var|continue|function|return|void|delete|if|this|do|while|else|in|switch|throw|try|typeof|with|debugger|class|enum|export|extends|import|super|get|set)(?:\W|$)/, 1, "webkit-javascript-keyword");
     989    this.findSingleLineString = this.generateFinder(/^"(?:[^"\\]|\\.)*"|^'([^'\\]|\\.)*'/, 0, "webkit-javascript-string"); // " this quote keeps Xcode happy
     990    this.findMultilineCommentStart = this.generateFinder(/^\/\*.*$/, 0, "webkit-javascript-comment");
     991    this.findMultilineCommentEnd = this.generateFinder(/^.*?\*\//, 0, "webkit-javascript-comment");
     992    this.findMultilineSingleQuoteStringStart = this.generateFinder(/^'(?:[^'\\]|\\.)*\\$/, 0, "webkit-javascript-string");
     993    this.findMultilineSingleQuoteStringEnd = this.generateFinder(/^(?:[^'\\]|\\.)*?'/, 0, "webkit-javascript-string");
     994    this.findMultilineDoubleQuoteStringStart = this.generateFinder(/^"(?:[^"\\]|\\.)*\\$/, 0, "webkit-javascript-string");
     995    this.findMultilineDoubleQuoteStringEnd = this.generateFinder(/^(?:[^"\\]|\\.)*?"/, 0, "webkit-javascript-string");
     996    this.findMultilineRegExpEnd = this.generateFinder(/^(?:[^\/\\]|\\.)*?\/([gim]{0,3})/, 0, "webkit-javascript-regexp");
     997    this.findSingleLineComment = this.generateFinder(/^\/\/.*|^\/\*.*?\*\//, 0, "webkit-javascript-comment");
     998}
     999
     1000WebInspector.JavaScriptSourceSyntaxHighlighter.prototype = {
     1001    deleteContinueFlags: function(cell)
     1002    {
     1003        if (!cell)
     1004            return;
     1005        delete cell._commentContinues;
     1006        delete cell._singleQuoteStringContinues;
     1007        delete cell._doubleQuoteStringContinues;
     1008        delete cell._regexpContinues;
     1009    },
     1010
     1011    findMultilineRegExpStart: function(str)
     1012    {
     1013        var match = /^\/(?:[^\/\\]|\\.)*\\$/.exec(str);
     1014        if (!match || !/\\|\$|\.[\?\*\+]|[^\|]\|[^\|]/.test(match[0]))
     1015            return null;
     1016        this.previousMatchLength = match[0].length;
     1017        return this.createSpan(match[0], "webkit-javascript-regexp");
     1018    },
     1019
     1020    findSingleLineRegExp: function(str)
     1021    {
     1022        var match = /^(\/(?:[^\/\\]|\\.)*\/([gim]{0,3}))(.?)/.exec(str);
     1023        if (!match || !(match[2].length > 0 || /\\|\$|\.[\?\*\+]|[^\|]\|[^\|]/.test(match[1]) || /\.|;|,/.test(match[3])))
     1024            return null;
     1025        this.previousMatchLength = match[1].length;
     1026        return this.createSpan(match[1], "webkit-javascript-regexp");
     1027    },
     1028
     1029    syntaxHighlightLine: function(line, prevLine)
     1030    {
     1031        var messageBubble = line.lastChild;
     1032        if (messageBubble && messageBubble.nodeType === Node.ELEMENT_NODE && messageBubble.hasStyleClass("webkit-html-message-bubble"))
     1033            line.removeChild(messageBubble);
     1034        else
     1035            messageBubble = null;
     1036
     1037        var code = line.textContent;
     1038
     1039        while (line.firstChild)
     1040            line.removeChild(line.firstChild);
     1041
     1042        var token;
     1043        var tmp = 0;
     1044        var i = 0;
     1045        this.previousMatchLength = 0;
     1046
     1047        if (prevLine) {
     1048            if (prevLine._commentContinues) {
     1049                if (!(token = this.findMultilineCommentEnd(code))) {
     1050                    token = this.createSpan(code, "webkit-javascript-comment");
     1051                    line._commentContinues = true;
     1052                }
     1053            } else if (prevLine._singleQuoteStringContinues) {
     1054                if (!(token = this.findMultilineSingleQuoteStringEnd(code))) {
     1055                    token = this.createSpan(code, "webkit-javascript-string");
     1056                    line._singleQuoteStringContinues = true;
     1057                }
     1058            } else if (prevLine._doubleQuoteStringContinues) {
     1059                if (!(token = this.findMultilineDoubleQuoteStringEnd(code))) {
     1060                    token = this.createSpan(code, "webkit-javascript-string");
     1061                    line._doubleQuoteStringContinues = true;
     1062                }
     1063            } else if (prevLine._regexpContinues) {
     1064                if (!(token = this.findMultilineRegExpEnd(code))) {
     1065                    token = this.createSpan(code, "webkit-javascript-regexp");
     1066                    line._regexpContinues = true;
     1067                }
     1068            }
     1069            if (token) {
     1070                i += this.previousMatchLength ? this.previousMatchLength : code.length;
     1071                tmp = i;
     1072                line.appendChild(token);
     1073            }
     1074        }
     1075
     1076        for ( ; i < code.length; ++i) {
     1077            var codeFragment = code.substr(i);
     1078            var prevChar = code[i - 1];
     1079            token = this.findSingleLineComment(codeFragment);
     1080            if (!token) {
     1081                if ((token = this.findMultilineCommentStart(codeFragment)))
     1082                    line._commentContinues = true;
     1083                else if (!prevChar || /^\W/.test(prevChar)) {
     1084                    token = this.findNumber(codeFragment) ||
     1085                            this.findKeyword(codeFragment) ||
     1086                            this.findSingleLineString(codeFragment) ||
     1087                            this.findSingleLineRegExp(codeFragment);
     1088                    if (!token) {
     1089                        if (token = this.findMultilineSingleQuoteStringStart(codeFragment))
     1090                            line._singleQuoteStringContinues = true;
     1091                        else if (token = this.findMultilineDoubleQuoteStringStart(codeFragment))
     1092                            line._doubleQuoteStringContinues = true;
     1093                        else if (token = this.findMultilineRegExpStart(codeFragment))
     1094                            line._regexpContinues = true;
     1095                    }
     1096                }
     1097            }
     1098
     1099            if (token) {
     1100                if (tmp !== i)
     1101                    line.appendChild(document.createTextNode(code.substring(tmp, i)));
     1102                line.appendChild(token);
     1103                i += this.previousMatchLength - 1;
     1104                tmp = i + 1;
     1105            }
     1106        }
     1107
     1108        if (tmp < code.length)
     1109            line.appendChild(document.createTextNode(code.substring(tmp, i)));
     1110
     1111        if (messageBubble)
     1112            line.appendChild(messageBubble);
     1113    }
     1114}
     1115
     1116WebInspector.JavaScriptSourceSyntaxHighlighter.prototype.__proto__ = WebInspector.SourceSyntaxHighligher.prototype;
  • trunk/WebCore/inspector/front-end/SourceView.js

    r46331 r49071  
    107107       
    108108        if (this.resource.type === WebInspector.Resource.Type.Script
    109             || this.resource.mimeType === 'application/json'
    110             || this.resource.mimeType === 'application/javascript'
     109            || this.resource.mimeType === "application/json"
     110            || this.resource.mimeType === "application/javascript"
    111111            || /\.js(on)?$/.test(this.resource.lastPathComponent) ) {
    112112            this.sourceFrame.addEventListener("syntax highlighting complete", this._syntaxHighlightingComplete, this);
    113113            this.sourceFrame.syntaxHighlightJavascript();
     114        } else if (this.resource.type === WebInspector.Resource.Type.Stylesheet
     115            || this.resource.mimeType === "text/css"
     116            || /\.css$/.test(this.resource.lastPathComponent) ) {
     117            this.sourceFrame.addEventListener("syntax highlighting complete", this._syntaxHighlightingComplete, this);
     118            this.sourceFrame.syntaxHighlightCSS();
    114119        } else
    115120            this._sourceFrameSetupFinished();
Note: See TracChangeset for help on using the changeset viewer.