Changeset 96703 in webkit


Ignore:
Timestamp:
Oct 5, 2011 7:30:29 AM (12 years ago)
Author:
vsevik@chromium.org
Message:

Web Inspector: Add support for search in script content.
https://bugs.webkit.org/show_bug.cgi?id=69015

Reviewed by Pavel Feldman.

Source/WebCore:

Tests: http/tests/inspector/search/search-in-concatenated-script.html

http/tests/inspector/search/search-in-script.html

  • inspector/Inspector.json:
  • inspector/InspectorDebuggerAgent.cpp:

(WebCore::InspectorDebuggerAgent::searchInContent):
(WebCore::InspectorDebuggerAgent::getScriptSource):

  • inspector/InspectorDebuggerAgent.h:
  • inspector/front-end/ContentProviders.js:

(WebInspector.ScriptContentProvider.prototype.searchInContent):
(WebInspector.ConcatenatedScriptsContentProvider.prototype._sortedScripts.var):
(WebInspector.ConcatenatedScriptsContentProvider.prototype._sortedScripts):
(WebInspector.ConcatenatedScriptsContentProvider.prototype.requestContent):
(WebInspector.ConcatenatedScriptsContentProvider.prototype.searchInContent.maybeCallback):
(WebInspector.ConcatenatedScriptsContentProvider.prototype.searchInContent.searchCallback):
(WebInspector.ConcatenatedScriptsContentProvider.prototype.searchInContent):
(WebInspector.ConcatenatedScriptsContentProvider.prototype._concatenateScriptsContent):

  • inspector/front-end/Script.js:

(WebInspector.Script.prototype.requestSource.didGetScriptSource):
(WebInspector.Script.prototype.requestSource):
(WebInspector.Script.prototype.searchInContent):

LayoutTests:

  • http/tests/inspector/resource-tree/resource-tree-test.js:

(initialize_ResourceTreeTest):

  • http/tests/inspector/resources-test.js:

(initialize_ResourceTest.InspectorTest.runAfterResourcesAreFinished):
(initialize_ResourceTest.InspectorTest._runAfterResourcesAreFinished):
(initialize_ResourceTest.InspectorTest._runAfterResourcesAreFinished.maybeCallback):
(initialize_ResourceTest.InspectorTest._runAfterResourcesAreFinished.addSniffer):
(initialize_ResourceTest.InspectorTest._runAfterResourcesAreFinished.resourceAddedToFrame):
(initialize_ResourceTest.InspectorTest._runAfterResourcesAreFinished.visit):
(initialize_ResourceTest):

  • http/tests/inspector/search/resources/search-concatenated.html: Added.
  • http/tests/inspector/search/search-in-concatenated-script-expected.txt: Added.
  • http/tests/inspector/search/search-in-concatenated-script.html: Added.
  • http/tests/inspector/search/search-in-resource.html:
  • http/tests/inspector/search/search-in-script-expected.txt: Added.
  • http/tests/inspector/search/search-in-script.html: Added.
  • http/tests/inspector/search/search-test.js:

(initialize_SearchTest):

  • inspector/debugger/content-providers.html:
  • platform/qt/Skipped:
Location:
trunk
Files:
5 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r96701 r96703  
     12011-10-05  Vsevolod Vlasov  <vsevik@chromium.org>
     2
     3        Web Inspector: Add support for search in script content.
     4        https://bugs.webkit.org/show_bug.cgi?id=69015
     5
     6        Reviewed by Pavel Feldman.
     7
     8        * http/tests/inspector/resource-tree/resource-tree-test.js:
     9        (initialize_ResourceTreeTest):
     10        * http/tests/inspector/resources-test.js:
     11        (initialize_ResourceTest.InspectorTest.runAfterResourcesAreFinished):
     12        (initialize_ResourceTest.InspectorTest._runAfterResourcesAreFinished):
     13        (initialize_ResourceTest.InspectorTest._runAfterResourcesAreFinished.maybeCallback):
     14        (initialize_ResourceTest.InspectorTest._runAfterResourcesAreFinished.addSniffer):
     15        (initialize_ResourceTest.InspectorTest._runAfterResourcesAreFinished.resourceAddedToFrame):
     16        (initialize_ResourceTest.InspectorTest._runAfterResourcesAreFinished.visit):
     17        (initialize_ResourceTest):
     18        * http/tests/inspector/search/resources/search-concatenated.html: Added.
     19        * http/tests/inspector/search/search-in-concatenated-script-expected.txt: Added.
     20        * http/tests/inspector/search/search-in-concatenated-script.html: Added.
     21        * http/tests/inspector/search/search-in-resource.html:
     22        * http/tests/inspector/search/search-in-script-expected.txt: Added.
     23        * http/tests/inspector/search/search-in-script.html: Added.
     24        * http/tests/inspector/search/search-test.js:
     25        (initialize_SearchTest):
     26        * inspector/debugger/content-providers.html:
     27        * platform/qt/Skipped:
     28
    1292011-10-05  Balazs Kelemen  <kbalazs@webkit.org>
    230
  • trunk/LayoutTests/http/tests/inspector/resource-tree/resource-tree-test.js

    r96576 r96703  
    8787}
    8888
    89 InspectorTest.runAfterResourcesAreFinished = function(resourceURLs, callback)
    90 {
    91     InspectorTest._runAfterResourcesAreFinished(resourceURLs.keySet(), callback);
    92 }
    93 
    94 InspectorTest._runAfterResourcesAreFinished = function(resourceURLs, callback)
    95 {
    96     function visit(resource)
    97     {
    98         if (!resource.finished)
    99             return true;
    100 
    101         for (var url in resourceURLs) {
    102             if (resource.url.indexOf(url) !== -1)
    103                 delete resourceURLs[url];
    104         }
    105 
    106         if (!Object.keys(resourceURLs).length) {
    107             callback();
    108             return true;
    109         }
    110     }
    111 
    112     var succeeded = WebInspector.resourceTreeModel.forAllResources(visit);
    113     if (!succeeded)
    114         setTimeout(InspectorTest._runAfterResourcesAreFinished.bind(InspectorTest, resourceURLs, callback), 0);
    115 }
    116 
    11789};
  • trunk/LayoutTests/http/tests/inspector/resources-test.js

    r96576 r96703  
    2828}
    2929
     30InspectorTest.runAfterResourcesAreFinished = function(resourceURLs, callback)
     31{
     32    InspectorTest._runAfterResourcesAreFinished(resourceURLs.keySet(), callback);
    3033}
     34
     35InspectorTest._runAfterResourcesAreFinished = function(resourceURLs, callback)
     36{
     37    function checkResource(resource)
     38    {
     39        for (var url in resourceURLs) {
     40            if (resource.url.indexOf(url) !== -1)
     41                delete resourceURLs[url];
     42        }
     43    }
     44
     45    function maybeCallback()
     46    {
     47        if (!Object.keys(resourceURLs).length) {
     48            callback();
     49            return true;
     50        }
     51    }
     52
     53    function addSniffer(resource)
     54    {
     55        InspectorTest.addSniffer(WebInspector.ResourceTreeModel.prototype, "_addResourceToFrame", resourceAddedToFrame.bind(this));
     56    }
     57
     58    function resourceAddedToFrame(resource)
     59    {
     60        checkResource(resource);
     61        if (!maybeCallback())
     62            addSniffer();
     63    }
     64
     65    function visit(resource)
     66    {
     67        checkResource(resource);
     68        return maybeCallback();
     69    }
     70
     71    var succeeded = WebInspector.resourceTreeModel.forAllResources(visit);
     72    if (!succeeded)
     73        addSniffer();
     74}
     75
     76}
  • trunk/LayoutTests/http/tests/inspector/search/search-in-resource.html

    r96576 r96703  
    22<head>
    33<script src="../inspector-test.js"></script>
     4<script src="../resources-test.js"></script>
    45<script src="search-test.js"></script>
    56<script>
     
    89    // This file should not match search query.
    910    var text = "searchTest" + "UniqueString";
    10     InspectorTest.runAfterResourcesAreCreated(["search.js"], step2);
     11    InspectorTest.runAfterResourcesAreFinished(["search.js"], step2);
    1112
    1213    function step2()
  • trunk/LayoutTests/http/tests/inspector/search/search-test.js

    r96576 r96703  
    1717};
    1818
    19 InspectorTest.runAfterResourcesAreCreated = function(resourceURLs, callback)
    20 {
    21     InspectorTest._runAfterResourcesAreCreated(resourceURLs.keySet(), callback);
    22 }
    23 
    24 InspectorTest._runAfterResourcesAreCreated = function(resourceURLs, callback)
    25 {
    26     function checkResource(resource)
    27     {
    28         for (var url in resourceURLs) {
    29             if (resource.url.indexOf(url) !== -1)
    30                 delete resourceURLs[url];
    31         }
    32     }
    33 
    34     function maybeCallback()
    35     {
    36         if (!Object.keys(resourceURLs).length) {
    37             callback();
    38             return true;
    39         }
    40     }
    41 
    42     function addSniffer(resource)
    43     {
    44         InspectorTest.addSniffer(WebInspector.ResourceTreeModel.prototype, "_bindResourceURL", onResourceBind.bind(this));
    45     }
    46 
    47     function onResourceBind(resource)
    48     {
    49         checkResource(resource);
    50         if (!maybeCallback())
    51             addSniffer();
    52     }
    53 
    54     function visit(resource)
    55     {
    56         checkResource(resource);
    57         return maybeCallback();
    58     }
    59 
    60     var succeeded = WebInspector.resourceTreeModel.forAllResources(visit);
    61     if (!succeeded)
    62         addSniffer();
    63 }
    64 
    6519};
  • trunk/LayoutTests/inspector/debugger/content-providers.html

    r95797 r96703  
    1616            },
    1717            get lineOffset() { return range[0]; },
    18             get columnOffset() { return range[1]; }
     18            get columnOffset() { return range[1]; },
     19            get endLine() { return range[2]; },
     20            get endColumn() { return range[3]; }
    1921        };
    2022    }
     
    3840        {
    3941            var scripts = [];
    40             scripts.push(createMockScript("1", "\nfunction baz()\n{\n  return 0;\n}\n", [3, 20]));
    41             scripts.push(createMockScript("2", "function foo() { return 0; }", [0, 10]));
    42             scripts.push(createMockScript("3", "function bar() { return 0; }", [1, 70]));
    43             scripts.push(createMockScript("4", "this should not appear in displayed content", [0, 20]));
     42            scripts.push(createMockScript("1", "\nfunction baz()\n{\n  return 0;\n}\n", [3, 20, 7, 0]));
     43            scripts.push(createMockScript("2", "function foo() { return 0; }", [0, 10, 0, 38]));
     44            scripts.push(createMockScript("3", "function bar() { return 0; }", [1, 70, 1, 98]));
     45            scripts.push(createMockScript("4", "this should not appear in displayed content", [0, 20, 0, 63]));
    4446            var contentProvider = new WebInspector.ConcatenatedScriptsContentProvider(scripts);
    4547            function didRequestContent(mimeType, content)
  • trunk/LayoutTests/platform/qt/Skipped

    r96678 r96703  
    23982398# https://bugs.webkit.org/show_bug.cgi?id=69257
    23992399inspector/styles/styles-disable-then-change.html
    2400 
    2401 # [Qt] REGRESSION(r95526): It made 3 inspector tests fail
    2402 # https://bugs.webkit.org/show_bug.cgi?id=69265
    2403 http/tests/inspector/search/search-in-concatenated-script.html
    2404 http/tests/inspector/search/search-in-script.html
    2405 inspector/debugger/script-formatter.html
  • trunk/Source/WebCore/ChangeLog

    r96702 r96703  
     12011-10-05  Vsevolod Vlasov  <vsevik@chromium.org>
     2
     3        Web Inspector: Add support for search in script content.
     4        https://bugs.webkit.org/show_bug.cgi?id=69015
     5
     6        Reviewed by Pavel Feldman.
     7
     8        Tests: http/tests/inspector/search/search-in-concatenated-script.html
     9               http/tests/inspector/search/search-in-script.html
     10
     11        * inspector/Inspector.json:
     12        * inspector/InspectorDebuggerAgent.cpp:
     13        (WebCore::InspectorDebuggerAgent::searchInContent):
     14        (WebCore::InspectorDebuggerAgent::getScriptSource):
     15        * inspector/InspectorDebuggerAgent.h:
     16        * inspector/front-end/ContentProviders.js:
     17        (WebInspector.ScriptContentProvider.prototype.searchInContent):
     18        (WebInspector.ConcatenatedScriptsContentProvider.prototype._sortedScripts.var):
     19        (WebInspector.ConcatenatedScriptsContentProvider.prototype._sortedScripts):
     20        (WebInspector.ConcatenatedScriptsContentProvider.prototype.requestContent):
     21        (WebInspector.ConcatenatedScriptsContentProvider.prototype.searchInContent.maybeCallback):
     22        (WebInspector.ConcatenatedScriptsContentProvider.prototype.searchInContent.searchCallback):
     23        (WebInspector.ConcatenatedScriptsContentProvider.prototype.searchInContent):
     24        (WebInspector.ConcatenatedScriptsContentProvider.prototype._concatenateScriptsContent):
     25        * inspector/front-end/Script.js:
     26        (WebInspector.Script.prototype.requestSource.didGetScriptSource):
     27        (WebInspector.Script.prototype.requestSource):
     28        (WebInspector.Script.prototype.searchInContent):
     29
    1302011-10-05  Alexis Menard  <alexis.menard@openbossa.org>
    231
  • trunk/Source/WebCore/inspector/Inspector.json

    r96597 r96703  
    17731773            },
    17741774            {
     1775                "name": "searchInContent",
     1776                "parameters": [
     1777                    { "name": "scriptId", "$ref": "ScriptId", "description": "Id of the script to search in." },
     1778                    { "name": "query", "type": "string", "description": "String to search for."  }
     1779                ],
     1780                "returns": [
     1781                    { "name": "result", "type": "array", "items": { "$ref": "Page.SearchMatch" }, "description": "List of search matches." }
     1782                ],
     1783                "description": "Searches for given string in script content."
     1784            },
     1785            {
    17751786                "name": "setScriptSource",
    17761787                "parameters": [
  • trunk/Source/WebCore/inspector/InspectorDebuggerAgent.cpp

    r96576 r96703  
    3232
    3333#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
     34#include "ContentSearchUtils.h"
    3435#include "InjectedScript.h"
    3536#include "InjectedScriptManager.h"
     
    321322}
    322323
     324void InspectorDebuggerAgent::searchInContent(ErrorString* error, const String& scriptId, const String& query, RefPtr<InspectorArray>* results)
     325{
     326    ScriptsMap::iterator it = m_scripts.find(scriptId);
     327    if (it != m_scripts.end())
     328        *results = ContentSearchUtils::searchInTextByLines(query, it->second.source);
     329    else
     330        *error = "No script for id: " + scriptId;
     331}
     332
    323333void InspectorDebuggerAgent::setScriptSource(ErrorString* error, const String& scriptId, const String& newContent, const bool* const preview, RefPtr<InspectorArray>* newCallFrames, RefPtr<InspectorObject>* result)
    324334{
     
    333343}
    334344
    335 void InspectorDebuggerAgent::getScriptSource(ErrorString*, const String& scriptId, String* scriptSource)
    336 {
    337     *scriptSource = m_scripts.get(scriptId).source;
     345void InspectorDebuggerAgent::getScriptSource(ErrorString* error, const String& scriptId, String* scriptSource)
     346{
     347    ScriptsMap::iterator it = m_scripts.find(scriptId);
     348    if (it != m_scripts.end())
     349        *scriptSource = it->second.source;
     350    else
     351        *error = "No script for id: " + scriptId;
    338352}
    339353
  • trunk/Source/WebCore/inspector/InspectorDebuggerAgent.h

    r96576 r96703  
    8282    void continueToLocation(ErrorString*, PassRefPtr<InspectorObject> location);
    8383
     84    void searchInContent(ErrorString*, const String& scriptId, const String& query, RefPtr<InspectorArray>*);
    8485    void setScriptSource(ErrorString*, const String& scriptId, const String& newContent, const bool* const preview, RefPtr<InspectorArray>* newCallFrames, RefPtr<InspectorObject>* result);
    8586    void getScriptSource(ErrorString*, const String& scriptId, String* scriptSource);
  • trunk/Source/WebCore/inspector/front-end/ContentProviders.js

    r96588 r96703  
    5151    searchInContent: function(query, callback)
    5252    {
    53         callback([]);
     53        this._script.searchInContent(query, callback);
    5454    }
    5555}
     
    6767};
    6868
     69WebInspector.ConcatenatedScriptsContentProvider.scriptOpenTag = "<script>";
     70WebInspector.ConcatenatedScriptsContentProvider.scriptCloseTag = "</script>";
     71
    6972WebInspector.ConcatenatedScriptsContentProvider.prototype = {
    70    requestContent: function(callback)
    71    {
    72        var scripts = this._scripts.slice();
    73        scripts.sort(function(x, y) { return x.lineOffset - y.lineOffset || x.columnOffset - y.columnOffset; });
    74        var sources = [];
    75        function didRequestSource(source)
    76        {
    77            sources.push(source);
    78            if (sources.length == scripts.length)
    79                callback(this._mimeType, this._concatenateScriptsContent(scripts, sources));
    80        }
    81        for (var i = 0; i < scripts.length; ++i)
    82            scripts[i].requestSource(didRequestSource.bind(this));
    83    },
    84 
    85     searchInContent: function(query, callback)
    86     {
    87         callback([]);
    88     },
    89 
    90    _concatenateScriptsContent: function(scripts, sources)
    91    {
    92        var content = "";
    93        var lineNumber = 0;
    94        var columnNumber = 0;
    95 
    96        function appendChunk(chunk)
    97        {
    98            content += chunk;
    99            var lineEndings = chunk.lineEndings();
    100            var lineCount = lineEndings.length;
    101            if (lineCount === 1)
    102                columnNumber += chunk.length;
    103            else {
    104                lineNumber += lineCount - 1;
    105                columnNumber = lineEndings[lineCount - 1] - lineEndings[lineCount - 2] - 1;
    106            }
    107        }
    108 
    109        var scriptOpenTag = "<script>";
    110        var scriptCloseTag = "</script>";
    111        for (var i = 0; i < scripts.length; ++i) {
    112            if (lineNumber > scripts[i].lineOffset || (lineNumber === scripts[i].lineOffset && columnNumber > scripts[i].columnOffset - scriptOpenTag.length))
    113                continue;
    114 
    115            // Fill the gap with whitespace characters.
    116            while (lineNumber < scripts[i].lineOffset)
    117                appendChunk("\n");
    118            while (columnNumber < scripts[i].columnOffset - scriptOpenTag.length)
    119                appendChunk(" ");
    120 
    121            // Add script tag.
    122            appendChunk(scriptOpenTag);
    123            appendChunk(sources[i]);
    124            appendChunk(scriptCloseTag);
    125        }
    126 
    127        return content;
    128    }
     73    _sortedScripts: function()
     74    {
     75        if (this._sortedScriptsArray)
     76            return this._sortedScriptsArray;
     77
     78        this._sortedScriptsArray = [];
     79       
     80        var scripts = this._scripts.slice();
     81        scripts.sort(function(x, y) { return x.lineOffset - y.lineOffset || x.columnOffset - y.columnOffset; });
     82       
     83        var scriptOpenTagLength = WebInspector.ConcatenatedScriptsContentProvider.scriptOpenTag.length;
     84        var scriptCloseTagLength = WebInspector.ConcatenatedScriptsContentProvider.scriptCloseTag.length;
     85       
     86        this._sortedScriptsArray.push(scripts[0]);
     87        for (var i = 1; i < scripts.length; ++i) {
     88            var previousScript = this._sortedScriptsArray[this._sortedScriptsArray.length - 1];
     89           
     90            var lineNumber = previousScript.endLine;
     91            var columnNumber = previousScript.endColumn + scriptCloseTagLength + scriptOpenTagLength;
     92           
     93            if (lineNumber < scripts[i].lineOffset || (lineNumber === scripts[i].lineOffset && columnNumber <= scripts[i].columnOffset))
     94                this._sortedScriptsArray.push(scripts[i]);
     95        }
     96        return this._sortedScriptsArray;
     97    },
     98
     99    requestContent: function(callback)
     100    {
     101        var scripts = this._sortedScripts();
     102        var sources = [];
     103        function didRequestSource(source)
     104        {
     105            sources.push(source);
     106            if (sources.length == scripts.length)
     107                callback(this._mimeType, this._concatenateScriptsContent(scripts, sources));
     108        }
     109        for (var i = 0; i < scripts.length; ++i)
     110            scripts[i].requestSource(didRequestSource.bind(this));
     111    },
     112
     113    searchInContent: function(query, callback)
     114    {
     115        var results = {};
     116        var scripts = this._sortedScripts();
     117        var scriptsLeft = scripts.length;
     118
     119        function maybeCallback()
     120        {
     121            if (scriptsLeft)
     122                return;
     123
     124            var result = [];
     125            for (var i = 0; i < scripts.length; ++i)
     126                result = result.concat(results[scripts[i].scriptId]);
     127            callback(result);
     128        }
     129
     130        function searchCallback(script, searchMatches)
     131        {
     132            results[script.scriptId] = [];
     133            for (var i = 0; i < searchMatches.length; ++i) {
     134                var searchMatch = {};
     135                searchMatch.lineNumber = searchMatches[i].lineNumber + script.lineOffset;
     136                searchMatch.lineContent = searchMatches[i].lineContent;
     137                results[script.scriptId].push(searchMatch);
     138            }
     139            scriptsLeft--;
     140            maybeCallback.call(this);
     141        }
     142
     143        maybeCallback();
     144        for (var i = 0; i < scripts.length; ++i)
     145            scripts[i].searchInContent(query, searchCallback.bind(this, scripts[i]));
     146    },
     147
     148    _concatenateScriptsContent: function(scripts, sources)
     149    {
     150        var content = "";
     151        var lineNumber = 0;
     152        var columnNumber = 0;
     153
     154        var scriptOpenTag = WebInspector.ConcatenatedScriptsContentProvider.scriptOpenTag;
     155        var scriptCloseTag = WebInspector.ConcatenatedScriptsContentProvider.scriptCloseTag;
     156        for (var i = 0; i < scripts.length; ++i) {
     157            // Fill the gap with whitespace characters.
     158            for (var newLinesCount = scripts[i].lineOffset - lineNumber; newLinesCount > 0; --newLinesCount) {
     159                columnNumber = 0;
     160                content += "\n";
     161            }
     162            for (var spacesCount = scripts[i].columnOffset - columnNumber - scriptOpenTag.length; spacesCount > 0; --spacesCount)
     163                content += " ";
     164
     165            // Add script tag.
     166            content += scriptOpenTag;
     167            content += sources[i];
     168            content += scriptCloseTag;
     169            lineNumber = scripts[i].endLine;
     170            columnNumber = scripts[i].endColumn + scriptCloseTag.length;
     171        }
     172
     173        return content;
     174    }
    129175}
    130176
  • trunk/Source/WebCore/inspector/front-end/Script.js

    r96576 r96703  
    5050        function didGetScriptSource(error, source)
    5151        {
    52             this._source = source;
     52            this._source = error ? "" : source;
    5353            callback(this._source);
    5454        }
     
    5656    },
    5757
     58    searchInContent: function(query, callback)
     59    {
     60        function innerCallback(error, searchMatches)
     61        {
     62            if (error)
     63                console.error(error);
     64            callback(searchMatches || []);
     65        }
     66       
     67        DebuggerAgent.searchInContent(this.scriptId, query, innerCallback.bind(this));
     68    },
     69   
    5870    editSource: function(newSource, callback)
    5971    {
Note: See TracChangeset for help on using the changeset viewer.