Web Inspector: Add support for search in single resource to page agent.
authorvsevik@chromium.org <vsevik@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 28 Sep 2011 15:01:41 +0000 (15:01 +0000)
committervsevik@chromium.org <vsevik@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 28 Sep 2011 15:01:41 +0000 (15:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=68998

Reviewed by Pavel Feldman.

Source/WebCore:

Test: http/tests/inspector/search/search-in-resource.html

* inspector/ContentSearchUtils.cpp:
(WebCore::ContentSearchUtils::getRegularExpressionMatchesByLines):
* inspector/ContentSearchUtils.h:
* inspector/Inspector.json:
* inspector/InspectorPageAgent.cpp:
(WebCore::buildObjectForSearchMatch):
(WebCore::InspectorPageAgent::searchInResource):
* inspector/InspectorPageAgent.h:
* inspector/front-end/Resource.js:
(WebInspector.Resource.prototype.searchInContent):
* inspector/front-end/SourceFile.js:
(WebInspector.ResourceContentProvider.prototype.requestContent):
(WebInspector.ResourceContentProvider.prototype.searchInContent):
* inspector/front-end/UISourceCode.js:
(WebInspector.ContentProvider.prototype.requestContent):
(WebInspector.ContentProvider.prototype.searchInContent):

LayoutTests:

* http/tests/inspector/search/search-in-resource-expected.txt: Added.
* http/tests/inspector/search/search-in-resource.html: Added.
* http/tests/inspector/search/search-in-resources.html:
* http/tests/inspector/search/search-test.js:
(initialize_SearchTest.InspectorTest.dumpSearchResults):
(initialize_SearchTest.InspectorTest.dumpSearchMatches):
(initialize_SearchTest):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96223 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/inspector/search/search-in-resource-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/inspector/search/search-in-resource.html [new file with mode: 0644]
LayoutTests/http/tests/inspector/search/search-in-resources.html
LayoutTests/http/tests/inspector/search/search-test.js
Source/WebCore/ChangeLog
Source/WebCore/inspector/ContentSearchUtils.cpp
Source/WebCore/inspector/ContentSearchUtils.h
Source/WebCore/inspector/Inspector.json
Source/WebCore/inspector/InspectorPageAgent.cpp
Source/WebCore/inspector/InspectorPageAgent.h
Source/WebCore/inspector/front-end/Resource.js
Source/WebCore/inspector/front-end/SourceFile.js
Source/WebCore/inspector/front-end/UISourceCode.js

index 09a884b..e3db172 100644 (file)
@@ -1,3 +1,18 @@
+2011-09-28  Vsevolod Vlasov  <vsevik@chromium.org>
+
+        Web Inspector: Add support for search in single resource to page agent.
+        https://bugs.webkit.org/show_bug.cgi?id=68998
+
+        Reviewed by Pavel Feldman.
+
+        * http/tests/inspector/search/search-in-resource-expected.txt: Added.
+        * http/tests/inspector/search/search-in-resource.html: Added.
+        * http/tests/inspector/search/search-in-resources.html:
+        * http/tests/inspector/search/search-test.js:
+        (initialize_SearchTest.InspectorTest.dumpSearchResults):
+        (initialize_SearchTest.InspectorTest.dumpSearchMatches):
+        (initialize_SearchTest):
+
 2011-09-28  Oliver Varga  <voliver@inf.u-szeged.hu>
 
         [WK2] SVG animation pause API missing
diff --git a/LayoutTests/http/tests/inspector/search/search-in-resource-expected.txt b/LayoutTests/http/tests/inspector/search/search-in-resource-expected.txt
new file mode 100644 (file)
index 0000000..8833983
--- /dev/null
@@ -0,0 +1,23 @@
+Tests single resource search in inspector page agent.
+
+Bug 68998  
+http://127.0.0.1:8000/inspector/search/resources/search.js
+Search matches: 
+lineNumber: 0, line: 'function searchTestUniqueString()'
+lineNumber: 3, line: '    // searchTestUniqueString two occurences on the same line searchTestUniqueString'
+lineNumber: 9, line: '    searchTestUniqueString();'
+lineNumber: 10, line: '    // SEARCHTestUniqueString();'
+
+http://127.0.0.1:8000/inspector/search/resources/search.css
+Search matches: 
+lineNumber: 0, line: 'div.searchTestUniqueString {'
+lineNumber: 4, line: 'div.searchTestUniqueString:hover {'
+lineNumber: 5, line: '    /* another searchTestUniqueString occurence */'
+
+http://127.0.0.1:8000/inspector/search/resources/search.html
+Search matches: 
+lineNumber: 5, line: '<div>searchTestUniqueString</div>'
+lineNumber: 7, line: '<!-- searchTestUniqueString -->'
+lineNumber: 9, line: '<div id="searchTestUniqueString">div text</div>'
+
+
diff --git a/LayoutTests/http/tests/inspector/search/search-in-resource.html b/LayoutTests/http/tests/inspector/search/search-in-resource.html
new file mode 100644 (file)
index 0000000..017ba38
--- /dev/null
@@ -0,0 +1,50 @@
+<html>
+<head>
+<script src="../inspector-test.js"></script>
+<script src="../resource-tree/resource-tree-test.js"></script>
+<script src="search-test.js"></script>
+<script>
+function test()
+{
+    // This file should not match search query.
+    var text = "searchTest" + "UniqueString";
+    InspectorTest.runAfterResourcesAreFinished(["search.js", "search.css", "search.html"], step2);
+
+    function step2()
+    {
+        var resource = WebInspector.resourceForURL("http://127.0.0.1:8000/inspector/search/resources/search.js");
+        InspectorTest.addResult(resource.url);
+        PageAgent.searchInResource(resource.frameId, resource.url, text, step3);
+    }
+
+    function step3(error, searchMatches)
+    {
+        InspectorTest.dumpSearchMatches(searchMatches);
+        var resource = WebInspector.resourceForURL("http://127.0.0.1:8000/inspector/search/resources/search.css");
+        InspectorTest.addResult(resource.url);
+        PageAgent.searchInResource(resource.frameId, resource.url, text, step4);
+    }
+
+    function step4(error, searchMatches)
+    {
+        InspectorTest.dumpSearchMatches(searchMatches);
+        var resource = WebInspector.resourceForURL("http://127.0.0.1:8000/inspector/search/resources/search.html");
+        InspectorTest.addResult(resource.url);
+        PageAgent.searchInResource(resource.frameId, resource.url, text, step5);
+    }
+
+    function step5(error, searchMatches)
+    {
+        InspectorTest.dumpSearchMatches(searchMatches);
+        InspectorTest.completeTest();
+    }
+}
+</script>
+</head>
+<body>
+<p>Tests single resource search in inspector page agent.</p>
+<a href="https://bugs.webkit.org/show_bug.cgi?id=68998">Bug 68998</a>
+
+<iframe src="resources/search.html" onload="runTest()">
+</body>
+</html>
index c17b346..2e7e7f3 100644 (file)
@@ -8,36 +8,32 @@ function test()
 {
     // This file should not match search query.
     var text = "searchTest" + "UniqueString";
-    InspectorTest.runAfterResourcesAreFinished(["search.js", "search.css", "search.html"], step2);
 
-    function step2()
-    {
-        InspectorTest.addResult("Case insensitive, non regex:");
-        PageAgent.searchInResources(text, false, false, step3);
-    }
+    InspectorTest.addResult("Case insensitive, non regex:");
+    PageAgent.searchInResources(text, false, false, step2);
 
-    function step3(error, searchResults)
+    function step2(error, searchResults)
     {
         InspectorTest.dumpSearchResults(searchResults);
         InspectorTest.addResult("Case sensitive, non regex:");
-        PageAgent.searchInResources(text, true, false, step4);
+        PageAgent.searchInResources(text, true, false, step3);
     }
 
-    function step4(error, searchResults)
+    function step3(error, searchResults)
     {
         InspectorTest.dumpSearchResults(searchResults);
         InspectorTest.addResult("Case insensitive, regex:");
-        PageAgent.searchInResources(text, false, true, step5);
+        PageAgent.searchInResources(text, false, true, step4);
     }
 
-    function step5(error, searchResults)
+    function step4(error, searchResults)
     {
         InspectorTest.dumpSearchResults(searchResults);
         InspectorTest.addResult("Case sensitive, regex:");
-        PageAgent.searchInResources(text, true, true, step6);
+        PageAgent.searchInResources(text, true, true, step5);
     }
 
-    function step6(error, searchResults)
+    function step5(error, searchResults)
     {
         InspectorTest.dumpSearchResults(searchResults);
         InspectorTest.completeTest();
index 9dd1975..651b8df 100644 (file)
@@ -6,6 +6,14 @@ InspectorTest.dumpSearchResults = function(searchResults)
     for (var i = 0; i < searchResults.length; i++)
         InspectorTest.addResult("url: " + searchResults[i].url + ", matchesCount: " + searchResults[i].matchesCount);
     InspectorTest.addResult("");
-}
+};
+
+InspectorTest.dumpSearchMatches = function(searchMatches)
+{
+    InspectorTest.addResult("Search matches: ");
+    for (var i = 0; i < searchMatches.length; i++)
+        InspectorTest.addResult("lineNumber: " + searchMatches[i].lineNumber + ", line: '" + searchMatches[i].lineContent + "'");
+    InspectorTest.addResult("");
+};
 
 };
index 9c6ce08..5659cda 100644 (file)
@@ -1,3 +1,29 @@
+2011-09-28  Vsevolod Vlasov  <vsevik@chromium.org>
+
+        Web Inspector: Add support for search in single resource to page agent.
+        https://bugs.webkit.org/show_bug.cgi?id=68998
+
+        Reviewed by Pavel Feldman.
+
+        Test: http/tests/inspector/search/search-in-resource.html
+
+        * inspector/ContentSearchUtils.cpp:
+        (WebCore::ContentSearchUtils::getRegularExpressionMatchesByLines):
+        * inspector/ContentSearchUtils.h:
+        * inspector/Inspector.json:
+        * inspector/InspectorPageAgent.cpp:
+        (WebCore::buildObjectForSearchMatch):
+        (WebCore::InspectorPageAgent::searchInResource):
+        * inspector/InspectorPageAgent.h:
+        * inspector/front-end/Resource.js:
+        (WebInspector.Resource.prototype.searchInContent):
+        * inspector/front-end/SourceFile.js:
+        (WebInspector.ResourceContentProvider.prototype.requestContent):
+        (WebInspector.ResourceContentProvider.prototype.searchInContent):
+        * inspector/front-end/UISourceCode.js:
+        (WebInspector.ContentProvider.prototype.requestContent):
+        (WebInspector.ContentProvider.prototype.searchInContent):
+
 2011-09-28  Ilya Tikhonovsky  <loislo@chromium.org>
 
         Web Inspector: It'd be useful to have performance stats for the back-end to front-end communication channel.
index 4cc22ab..2c9c7c4 100644 (file)
 
 #if ENABLE(INSPECTOR)
 
+#include "InspectorValues.h"
 #include "RegularExpression.h"
 
+using namespace std;
+
 namespace WebCore {
 namespace ContentSearchUtils {
 
@@ -56,6 +59,44 @@ static String createSearchRegexSource(const String& text)
     return result;
 }
 
+static Vector<pair<int, String> > getRegularExpressionMatchesByLines(const RegularExpression& regex, const String& text)
+{
+    Vector<pair<int, String> > result;
+
+    int lineNumber = 0;
+    unsigned start = 0;
+    while (start < text.length()) {
+        size_t lineEnd = text.find('\n', start);
+        if (lineEnd == notFound)
+            lineEnd = text.length();
+        else
+            lineEnd++;
+
+        String line = text.substring(start, lineEnd - start);
+        if (line.endsWith("\r\n"))
+            line = line.left(line.length() - 2);
+        if (line.endsWith("\n"))
+            line = line.left(line.length() - 1);
+
+        int matchLength;
+        if (regex.match(line, 0, &matchLength) != -1)
+            result.append(pair<int, String>(lineNumber, line));
+
+        start = lineEnd;
+        lineNumber++;
+    }
+    return result;
+}
+
+static PassRefPtr<InspectorObject> buildObjectForSearchMatch(int lineNumber, String lineContent)
+{
+    RefPtr<InspectorObject> result = InspectorObject::create();
+    result->setNumber("lineNumber", lineNumber);
+    result->setString("lineContent", lineContent);
+
+    return result;
+}
+
 RegularExpression createSearchRegex(const String& text, bool caseSensitive, bool isRegex)
 {
     String regexSource = isRegex ? text : createSearchRegexSource(text);
@@ -78,6 +119,19 @@ int countRegularExpressionMatches(const RegularExpression& regex, const String&
     return result;
 }
 
+PassRefPtr<InspectorArray> searchInTextByLines(const String& query, const String& text)
+{
+    RefPtr<InspectorArray> result = InspectorArray::create();
+
+    RegularExpression regex = ContentSearchUtils::createSearchRegex(query, false, false);
+    Vector<pair<int, String> > matches = getRegularExpressionMatchesByLines(regex, text);
+
+    for (Vector<pair<int, String> >::const_iterator it = matches.begin(); it != matches.end(); ++it)
+        result->pushValue(buildObjectForSearchMatch(it->first, it->second));
+
+    return result;
+}
+
 } // namespace ContentSearchUtils
 } // namespace WebCore
 
index 6515450..33e692e 100644 (file)
 
 #include "PlatformString.h"
 
+#include <wtf/Vector.h>
+
 namespace WebCore {
 
+class InspectorArray;
 class RegularExpression;
 
 namespace ContentSearchUtils {
 
 RegularExpression createSearchRegex(const String& text, bool caseSensitive, bool isRegex);
 int countRegularExpressionMatches(const RegularExpression&, const String&);
+PassRefPtr<InspectorArray> searchInTextByLines(const String& query, const String& text);
 
 } // namespace ContentSearchUtils
 } // namespace WebCore
index 2a5f9dc..650c63c 100644 (file)
                 "hidden": true
             },
             {
+                "id": "SearchMatch",
+                "type": "object",
+                "description": "Search match for resource.",
+                "properties": [
+                    { "name": "lineNumber", "type": "number", "description": "Line number in resource content." },
+                    { "name": "lineContent", "type": "string", "description": "Line with match content." }
+                ],
+                "hidden": true
+            },
+            {
                 "id": "SearchResult",
                 "type": "object",
                 "description": "Search result for resource.",
                 "hidden": true
             },
             {
+                "name": "searchInResource",
+                "description": "Searches for given string in resource content.",
+                "parameters": [
+                    { "name": "frameId", "type": "string", "description": "Frame id for resource to search in." },
+                    { "name": "url", "type": "string", "description": "URL of the resource to search in." },
+                    { "name": "query", "type": "string", "description": "String to search for."  }
+                ],
+                "returns": [
+                    { "name": "result", "type": "array", "items": { "$ref": "SearchMatch" }, "description": "List of search matches." }
+                ],
+                "hidden": true
+            },
+            {
                 "name": "searchInResources",
                 "description": "Searches for given string in frame / resource tree structure.",
                 "parameters": [
index 9e9aed6..b6848f1 100644 (file)
@@ -67,6 +67,8 @@
 #include <wtf/ListHashSet.h>
 #include <wtf/Vector.h>
 
+using namespace std;
+
 namespace WebCore {
 
 namespace PageAgentState {
@@ -482,6 +484,39 @@ static bool textContentForCachedResource(CachedResource* cachedResource, String*
     return false;
 }
 
+void InspectorPageAgent::searchInResource(ErrorString*, const String& frameId, const String& url, const String& query, RefPtr<InspectorArray>* object)
+{
+    RefPtr<InspectorArray> result = InspectorArray::create();
+
+    Frame* frame = frameForId(frameId);
+    KURL kurl(ParsedURLString, url);
+
+    FrameLoader* frameLoader = frame ? frame->loader() : 0;
+    DocumentLoader* loader = frameLoader ? frameLoader->documentLoader() : 0;
+    if (!loader) {
+        *object = result;
+        return;
+    }
+
+    String content;
+    bool success = false;
+    if (equalIgnoringFragmentIdentifier(kurl, loader->url()))
+        success = mainResourceContent(frame, false, &content);
+
+    if (!success) {
+        CachedResource* resource = cachedResource(frame, kurl);
+        success = textContentForCachedResource(resource, &content);
+    }
+
+    if (!success) {
+        *object = result;
+        return;
+    }
+
+    result = ContentSearchUtils::searchInTextByLines(query, content);
+    *object = result;
+}
+
 static PassRefPtr<InspectorObject> buildObjectForSearchResult(const String& frameId, const String& url, int matchesCount)
 {
     RefPtr<InspectorObject> result = InspectorObject::create();
index defa156..9130c50 100644 (file)
@@ -97,6 +97,7 @@ public:
     void deleteCookie(ErrorString*, const String& cookieName, const String& domain);
     void getResourceTree(ErrorString*, RefPtr<InspectorObject>*);
     void getResourceContent(ErrorString*, const String& frameId, const String& url, String* content, bool* base64Encoded);
+    void searchInResource(ErrorString*, const String& frameId, const String& url, const String&, RefPtr<InspectorArray>*);
     void searchInResources(ErrorString*, const String&, const bool* const caseSensitive, const bool* const isRegex, RefPtr<InspectorArray>*);
 
     // InspectorInstrumentation API
index 979a676..422a9b7 100644 (file)
@@ -867,6 +867,11 @@ WebInspector.Resource.prototype = {
             this._innerRequestContent();
     },
 
+    searchInContent: function(query, callback)
+    {
+        PageAgent.searchInResource(query, callback);
+    },
+
     populateImageSource: function(image)
     {
         function onResourceContent()
index 168789d..165aa95 100644 (file)
@@ -358,7 +358,12 @@ WebInspector.ResourceContentProvider.prototype = {
             callback(this._mimeType, content);
         }
         this._resource.requestContent(didRequestContent.bind(this));
-    }
+    },
+    
+    searchInContent: function(query, callback)
+    {
+        this._resource.searchInContent(query, callback);
+    }    
 }
 
 WebInspector.ResourceContentProvider.prototype.__proto__ = WebInspector.ContentProvider.prototype;
index 4dc6fad..23ffbda 100644 (file)
@@ -90,5 +90,6 @@ WebInspector.UISourceCode.prototype = {
  */
 WebInspector.ContentProvider = function() { }
 WebInspector.ContentProvider.prototype = {
-    requestContent: function(callback) { }
+    requestContent: function(callback) { },
+    searchInContent: function(query, callback) { }
 }