[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
loislo at chromium.org
loislo at chromium.org
Wed Dec 22 11:38:28 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 6a07f07ffe5acc63ca14e52486c2bd1162f8bea6
Author: loislo at chromium.org <loislo at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Aug 2 12:55:56 2010 +0000
ndrey Kosyakov <caseq at chromium.org>
Reviewed by Pavel Feldman.
Web Inspector: adding experimental support for WebInspector extensions API.
https://bugs.webkit.org/show_bug.cgi?id=40425
Tests: inspector/extensions-api.html
inspector/extensions.html
* WebCore.gypi:
* WebCore.vcproj/WebCore.vcproj:
* inspector/InspectorController.cpp:
(WebCore::InspectorController::inspectedWindowScriptObjectCleared):
(WebCore::InspectorController::didCommitLoad):
* inspector/InspectorFrontendHost.cpp:
(WebCore::InspectorFrontendHost::setExtensionAPI):
* inspector/InspectorFrontendHost.h:
* inspector/InspectorFrontendHost.idl:
* inspector/front-end/ElementsPanel.js:
(WebInspector.ElementsPanel.this.treeOutline.focusedNodeChanged):
(WebInspector.ElementsPanel):
* inspector/front-end/ExtensionAPI.js: Added. An API implementation that gets injected into the extension context.
(injectedExtensionAPI):
(injectedExtensionAPI.EventSinkImpl.prototype.addListener):
(injectedExtensionAPI.EventSinkImpl.prototype.removeListener):
(injectedExtensionAPI.EventSinkImpl.prototype._fire):
(injectedExtensionAPI.EventSink):
(injectedExtensionAPI.InspectorExtensionAPI):
(injectedExtensionAPI.InspectorExtensionAPI.prototype.log):
(injectedExtensionAPI.Resources.prototype.getAll):
(injectedExtensionAPI.Resources.prototype.get return):
(injectedExtensionAPI.Resources.prototype):
(injectedExtensionAPI.Panels):
(injectedExtensionAPI.Panels.prototype.create.callbackWrapper):
(injectedExtensionAPI.Panels.prototype.create):
(injectedExtensionAPI.PanelImpl):
(injectedExtensionAPI.PanelImpl.prototype.createSidebarPane.callbackWrapper):
(injectedExtensionAPI.PanelImpl.prototype.createSidebarPane):
(injectedExtensionAPI.ExtensionPanel):
(injectedExtensionAPI.ExtensionSidebarPaneImpl):
(injectedExtensionAPI.ExtensionSidebarPaneImpl.prototype.setHeight):
(injectedExtensionAPI.ExtensionSidebarPaneImpl.prototype.setExpanded):
(injectedExtensionAPI.InspectedWindow):
(injectedExtensionAPI.InspectedWindow.prototype.reload):
(injectedExtensionAPI.InspectedWindow.prototype.evaluate):
(injectedExtensionAPI.ExtensionServerClient.prototype.sendRequest):
(injectedExtensionAPI.ExtensionServerClient.prototype.registerHandler):
(injectedExtensionAPI.ExtensionServerClient.prototype.nextObjectId):
(injectedExtensionAPI.ExtensionServerClient.prototype._registerCallback):
(injectedExtensionAPI.ExtensionServerClient.prototype._onCallback):
(injectedExtensionAPI.ExtensionServerClient.prototype._onMessage):
(injectedExtensionAPI.expandURL):
(injectedExtensionAPI.):
* inspector/front-end/ExtensionPanel.js: Added. A class that provides WebInspector's Panel interface to the inspector, hosts extension panel within an IFrame and proxies Panel callbacks to the extension
.
(WebInspector.ExtensionPanel):
(WebInspector.ExtensionPanel.prototype.get defaultFocusedElement):
(WebInspector.ExtensionPanel.prototype.updateMainViewWidth):
(WebInspector.ExtensionPanel.prototype.searchCanceled):
(WebInspector.ExtensionPanel.prototype.performSearch):
(WebInspector.ExtensionPanel.prototype.jumpToNextSearchResult):
(WebInspector.ExtensionPanel.prototype.jumpToPreviousSearchResult):
(WebInspector.ExtensionPanel.prototype._addStyleRule):
* inspector/front-end/ExtensionRegistryStub.js: Added. A stub for ExtensionRegistry class that is meant to provide a list of extensions. Actual implementations may be browser-specfic.
(.WebInspector.InspectorExtensionRegistryStub):
(.WebInspector.InspectorExtensionRegistryStub.prototype.getExtensionsAsync):
* inspector/front-end/ExtensionServer.js: Added. Communicates with ExtensionAPI via DOM messaging and proxies requests to WebInspector classes.
(WebInspector.ExtensionServer):
(WebInspector.ExtensionServer.prototype.notifyPanelShown):
(WebInspector.ExtensionServer.prototype.notifyObjectSelected):
(WebInspector.ExtensionServer.prototype.notifyResourceFinished):
(WebInspector.ExtensionServer.prototype.notifySearchAction):
(WebInspector.ExtensionServer.prototype.notifyInspectedPageLoaded):
(WebInspector.ExtensionServer.prototype.notifyInspectedURLChanged):
(WebInspector.ExtensionServer.prototype.notifyInspectorReset):
(WebInspector.ExtensionServer.prototype._convertResource):
(WebInspector.ExtensionServer.prototype._postNotification):
(WebInspector.ExtensionServer.prototype._onSubscribe):
(WebInspector.ExtensionServer.prototype._onUnsubscribe):
(WebInspector.ExtensionServer.prototype._onCreatePanel):
(WebInspector.ExtensionServer.prototype._onCreateSidebar):
(WebInspector.ExtensionServer.prototype._createClientIframe):
(WebInspector.ExtensionServer.prototype._onSetSidebarHeight):
(WebInspector.ExtensionServer.prototype._onSetSidebarExpansion):
(WebInspector.ExtensionServer.prototype._onLog):
(WebInspector.ExtensionServer.prototype._onEvaluateOnInspectedPage):
(WebInspector.ExtensionServer.prototype._onRevealAndSelect):
(WebInspector.ExtensionServer.prototype._onRevealAndSelectResource):
(WebInspector.ExtensionServer.prototype._dispatchCallback):
(WebInspector.ExtensionServer.prototype._onGetResources):
(WebInspector.ExtensionServer.prototype.initExtensions):
(WebInspector.ExtensionServer.prototype._addExtensions):
(WebInspector.ExtensionServer.prototype._onWindowMessage):
(WebInspector.ExtensionServer.prototype._onmessage):
(WebInspector.ExtensionServer.prototype._registerHandler):
(WebInspector.ExtensionStatus):
(WebInspector.addExtensions):
* inspector/front-end/InjectedScript.js:
(injectedScriptConstructor):
* inspector/front-end/InjectedScriptAccess.js:
* inspector/front-end/InspectorFrontendHostStub.js:
(.WebInspector.InspectorFrontendHostStub.prototype.setExtensionAPI):
(.WebInspector.InspectorFrontendHostStub.prototype.canAttachWindow):
* inspector/front-end/WebKit.qrc:
* inspector/front-end/inspector.html:
* inspector/front-end/inspector.js:
(WebInspector.loaded):
(WebInspector.updateResource):
(WebInspector.reset):
(WebInspector.inspectedURLChanged):
(WebInspector.didCommitLoad):
2010-08-02 Andrey Kosyakov <caseq at chromium.org>
Reviewed by Pavel Feldman.
Web Inspector: adding tests for WebInspector extensions API.
https://bugs.webkit.org/show_bug.cgi?id=40425
* http/tests/inspector/inspector-test.js:
(dumpObject):
* inspector/extensions-api-expected.txt: Added.
* inspector/extensions-api.html: Added.
* inspector/extensions-expected.txt: Added.
* inspector/extensions-test.js: Added.
(log):
(frontend_initializeExtension):
(doit):
(done.callback):
(done):
(extensionFunctions):
* inspector/extensions.html: Added.
* inspector/resources/extension-main.html: Added.
* inspector/resources/extension-main.js: Added.
(fetchTests.callback):
(fetchTests):
(runTests):
(onTestsDone):
(runTest):
(callbackAndNextTest.callbackWrapper):
(callbackAndNextTest):
(output):
* inspector/resources/extension-panel.html: Added.
* inspector/resources/extension-sidebar.html: Added.
* platform/chromium/test_expectations.txt:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@64458 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index f778493..b881c57 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,37 @@
+2010-08-02 Andrey Kosyakov <caseq at chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: adding tests for WebInspector extensions API.
+ https://bugs.webkit.org/show_bug.cgi?id=40425
+
+ * http/tests/inspector/inspector-test.js:
+ (dumpObject):
+ * inspector/extensions-api-expected.txt: Added.
+ * inspector/extensions-api.html: Added.
+ * inspector/extensions-expected.txt: Added.
+ * inspector/extensions-test.js: Added.
+ (log):
+ (frontend_initializeExtension):
+ (doit):
+ (done.callback):
+ (done):
+ (extensionFunctions):
+ * inspector/extensions.html: Added.
+ * inspector/resources/extension-main.html: Added.
+ * inspector/resources/extension-main.js: Added.
+ (fetchTests.callback):
+ (fetchTests):
+ (runTests):
+ (onTestsDone):
+ (runTest):
+ (callbackAndNextTest.callbackWrapper):
+ (callbackAndNextTest):
+ (output):
+ * inspector/resources/extension-panel.html: Added.
+ * inspector/resources/extension-sidebar.html: Added.
+ * platform/chromium/test_expectations.txt:
+
2010-08-02 Csaba Osztrogonác <ossy at webkit.org>
Unreviewed.
diff --git a/LayoutTests/http/tests/inspector/inspector-test.js b/LayoutTests/http/tests/inspector/inspector-test.js
index f412509..40ace31 100755
--- a/LayoutTests/http/tests/inspector/inspector-test.js
+++ b/LayoutTests/http/tests/inspector/inspector-test.js
@@ -54,6 +54,8 @@ function dumpObject(object, nondeterministicProps, prefix, firstLinePrefix)
dumpObject(propValue, nondeterministicProps, prefix + " ", prefixWithName);
else if (typeof propValue === "string")
output(prefixWithName + "\"" + propValue + "\"");
+ else if (typeof propValue === "function")
+ output(prefixWithName + "<function>");
else
output(prefixWithName + propValue);
}
diff --git a/LayoutTests/inspector/extensions-api-expected.txt b/LayoutTests/inspector/extensions-api-expected.txt
new file mode 100644
index 0000000..8f1a32d
--- /dev/null
+++ b/LayoutTests/inspector/extensions-api-expected.txt
@@ -0,0 +1,47 @@
+Tests public interface of WebInspector Extensions API
+
+Started extension.
+Running tests...
+RUNNING TEST: extension_testAPI
+{
+ inspectedWindow : {
+ onLoaded : {
+ addListener : <function>
+ removeListener : <function>
+ }
+ onNavigated : {
+ addListener : <function>
+ removeListener : <function>
+ }
+ onDOMContentLoaded : {
+ addListener : <function>
+ removeListener : <function>
+ }
+ reload : <function>
+ evaluate : <function>
+ }
+ panels : {
+ elements : {
+ createSidebarPane : <function>
+ }
+ scripts : {
+ createSidebarPane : <function>
+ }
+ create : <function>
+ }
+ resources : {
+ onFinished : {
+ addListener : <function>
+ removeListener : <function>
+ }
+ getAll : <function>
+ get : <function>
+ }
+ onReset : {
+ addListener : <function>
+ removeListener : <function>
+ }
+ log : <function>
+}
+All tests done.
+
diff --git a/LayoutTests/inspector/extensions-api.html b/LayoutTests/inspector/extensions-api.html
new file mode 100644
index 0000000..560cff7
--- /dev/null
+++ b/LayoutTests/inspector/extensions-api.html
@@ -0,0 +1,18 @@
+<html>
+<head>
+<script src="../http/tests/inspector/inspector-test.js"></script>
+<script src="extensions-test.js"></script>
+<script type="text/javascript">
+
+function extension_testAPI(nextTest)
+{
+ dumpObject(webInspector);
+ nextTest();
+}
+
+</script>
+</head>
+<body onload="onload()">
+<p>Tests public interface of WebInspector Extensions API</p>
+</body>
+</html>
diff --git a/LayoutTests/inspector/extensions-expected.txt b/LayoutTests/inspector/extensions-expected.txt
new file mode 100644
index 0000000..688c666
--- /dev/null
+++ b/LayoutTests/inspector/extensions-expected.txt
@@ -0,0 +1,34 @@
+Tests WebInspector extension API
+
+Started extension.
+Running tests...
+RUNNING TEST: extension_testCreatePanel
+done createPanel
+Panel created
+{
+ createSidebarPane : <function>
+ onSearch : {
+ addListener : <function>
+ removeListener : <function>
+ }
+}
+RUNNING TEST: extension_testCreateSidebar
+Sidebar created
+{
+ setHeight : <function>
+ setExpanded : <function>
+}
+RUNNING TEST: extension_testEvalFailed
+Evaluate: TypeError: JSON.stringify cannot serialize cyclic structures.(exception: true)
+RUNNING TEST: extension_testEvalOk
+Evaluate: {"str":"foo","num":42}(exception: undefined)
+RUNNING TEST: extension_testGetAllResources
+resource: .../tests/inspector/inspector-test.js
+resource: .../LayoutTests/inspector/extensions-test.js
+resource: .../LayoutTests/inspector/extensions.html
+RUNNING TEST: extension_testGetInvalidResource
+Attempted to retrieve invalid resource: {"code":"E_NOTFOUND","description":"Object not found (%s)","details":[2128506],"isError":true}
+RUNNING TEST: extension_testResourceNotification
+Resource finished: .../inspector/resources/extension-main.html
+All tests done.
+
diff --git a/LayoutTests/inspector/extensions-test.js b/LayoutTests/inspector/extensions-test.js
new file mode 100644
index 0000000..00d8ef5
--- /dev/null
+++ b/LayoutTests/inspector/extensions-test.js
@@ -0,0 +1,38 @@
+function log(message)
+{
+ output(message);
+}
+
+function frontend_initializeExtension(url)
+{
+ if (WebInspector.panels.resources.resourceTrackingEnabled)
+ WebInspector.addExtensions([{ startPage: url }]);
+ else
+ InspectorBackend.enableResourceTracking(false);
+}
+
+function doit()
+{
+ var extensionURL = location.href.replace(/\/[^/]*$/, "/resources/extension-main.html");
+ evaluateInWebInspector("frontend_initializeExtension('" + extensionURL + "')");
+}
+
+function done()
+{
+ function callback()
+ {
+ notifyDone();
+ }
+ evaluateInWebInspector("InspectorBackend.disableResourceTracking(false);", callback);
+}
+
+function extensionFunctions()
+{
+ var functions = "";
+
+ for (symbol in window) {
+ if (/^extension_/.exec(symbol) && typeof window[symbol] === "function")
+ functions += window[symbol].toString();
+ }
+ return functions;
+}
diff --git a/LayoutTests/inspector/extensions.html b/LayoutTests/inspector/extensions.html
new file mode 100644
index 0000000..63c682b
--- /dev/null
+++ b/LayoutTests/inspector/extensions.html
@@ -0,0 +1,87 @@
+<html>
+<head>
+<script src="../http/tests/inspector/inspector-test.js"></script>
+<script src="extensions-test.js"></script>
+<script type="text/javascript">
+
+window.inspectedValue = { str: "foo", num: 42 };
+
+function extension_testEvalOk(nextTest)
+{
+ webInspector.inspectedWindow.evaluate("inspectedValue", callbackAndNextTest(extension_onEvaluate, nextTest));
+}
+
+function extension_testEvalFailed(nextTest)
+{
+ webInspector.inspectedWindow.evaluate("document.body", callbackAndNextTest(extension_onEvaluate, nextTest));
+}
+
+function extension_testGetAllResources(nextTest)
+{
+ function compareResources(a, b)
+ {
+ return a.har.request.url.localeCompare(b.har.request.url);
+ }
+
+ function onResource(result)
+ {
+ var resources = result.sort(compareResources);
+
+ for (var i = 0; i < resources.length; ++i)
+ log("resource: " + resources[i].har.request.url.replace(/.*((\/[^/]*){3}$)/,"...$1"));
+ }
+ webInspector.resources.getAll(callbackAndNextTest(onResource, nextTest));
+}
+
+function extension_testGetInvalidResource(nextTest)
+{
+ function onResource(result)
+ {
+ log("Attempted to retrieve invalid resource: " + JSON.stringify(result));
+ }
+ webInspector.resources.get(2128506, callbackAndNextTest(onResource, nextTest));
+}
+
+function extension_testCreatePanel(nextTest)
+{
+ function onPanelCreated(panel)
+ {
+ log("Panel created");
+ dumpObject(panel);
+ }
+ webInspector.panels.create("Test Panel", "extension-panel.html", "extension-panel.png", callbackAndNextTest(onPanelCreated, nextTest));
+ log("done createPanel");
+}
+
+function extension_testCreateSidebar(nextTest)
+{
+ function onSidebarCreated(sidebar)
+ {
+ log("Sidebar created");
+ dumpObject(sidebar);
+ }
+ webInspector.panels.scripts.createSidebarPane("Test Sidebar", "extension-sidebar.html", callbackAndNextTest(onSidebarCreated, nextTest));
+}
+
+function extension_testResourceNotification(nextTest)
+{
+ function onResourceFinished(resource)
+ {
+ log("Resource finished: " + resource.har.request.url.replace(/.*((\/[^/]*){3}$)/,"...$1"));
+ }
+
+ webInspector.resources.onFinished.addListener(callbackAndNextTest(onResourceFinished, nextTest));
+ webInspector.inspectedWindow.evaluate("var xhr = new XMLHttpRequest(); xhr.open('GET', '" + location.href + "', false); xhr.send(null);");
+}
+
+function extension_onEvaluate(result)
+{
+ log("Evaluate: " + result.value + "(exception: " + result.isException + ")");
+}
+
+</script>
+</head>
+<body onload="onload()">
+<p>Tests WebInspector extension API</p>
+</body>
+</html>
diff --git a/LayoutTests/inspector/resources/extension-main.html b/LayoutTests/inspector/resources/extension-main.html
new file mode 100644
index 0000000..e068e8f
--- /dev/null
+++ b/LayoutTests/inspector/resources/extension-main.html
@@ -0,0 +1,15 @@
+<html>
+<head>
+<script type="text/javascript">
+function log(message)
+{
+ webInspector.inspectedWindow.evaluate("log(unescape('" + escape(message) + "'));");
+}
+
+log("Started extension.");
+</script>
+
+<script src="../../http/tests/inspector/inspector-test.js"></script>
+<script src="extension-main.js"></script>
+</head>
+</html>
diff --git a/LayoutTests/inspector/resources/extension-main.js b/LayoutTests/inspector/resources/extension-main.js
new file mode 100644
index 0000000..9bc6bb3
--- /dev/null
+++ b/LayoutTests/inspector/resources/extension-main.js
@@ -0,0 +1,66 @@
+function fetchTests()
+{
+ function callback(result)
+ {
+ var functions = JSON.parse(result.value);
+ window.eval(functions);
+ runTests();
+ }
+ webInspector.inspectedWindow.evaluate("extensionFunctions()", callback);
+}
+
+function runTests()
+{
+ log("Running tests...");
+ var tests = [];
+ for (var symbol in this) {
+ if (/^extension_test/.exec(symbol) && typeof this[symbol] === "function")
+ tests.push(symbol);
+ }
+ tests = tests.sort();
+ var testChain = onTestsDone;
+ for (var test = tests.pop(); test; test = tests.pop())
+ testChain = bind(runTest, this, bind(this[test], this, testChain), test);
+ testChain();
+}
+
+function onTestsDone()
+{
+ log("All tests done.");
+ webInspector.inspectedWindow.evaluate("done();");
+}
+
+function runTest(test, name)
+{
+ log("RUNNING TEST: " + name);
+ try {
+ test();
+ } catch (e) {
+ log(name + ": " + e);
+ }
+}
+
+function callbackAndNextTest(callback, nextTest)
+{
+ function callbackWrapper()
+ {
+ callback.apply(this, arguments);
+ nextTest.call(this);
+ }
+ return callbackWrapper;
+}
+
+function bind(func, thisObject)
+{
+ var args = Array.prototype.slice.call(arguments, 2);
+ return function() { return func.apply(thisObject, args.concat(Array.prototype.slice.call(arguments, 0))); };
+}
+
+// dumpObject() needs output(), so implement it via log().
+
+function output(msg)
+{
+ log(msg);
+}
+
+fetchTests();
diff --git a/LayoutTests/inspector/resources/extension-panel.html b/LayoutTests/inspector/resources/extension-panel.html
new file mode 100644
index 0000000..90531a4
--- /dev/null
+++ b/LayoutTests/inspector/resources/extension-panel.html
@@ -0,0 +1,2 @@
+<html>
+</html>
diff --git a/LayoutTests/inspector/resources/extension-sidebar.html b/LayoutTests/inspector/resources/extension-sidebar.html
new file mode 100644
index 0000000..90531a4
--- /dev/null
+++ b/LayoutTests/inspector/resources/extension-sidebar.html
@@ -0,0 +1,2 @@
+<html>
+</html>
diff --git a/LayoutTests/platform/chromium/test_expectations.txt b/LayoutTests/platform/chromium/test_expectations.txt
index e991bbc..2c90e6b 100644
--- a/LayoutTests/platform/chromium/test_expectations.txt
+++ b/LayoutTests/platform/chromium/test_expectations.txt
@@ -198,6 +198,7 @@ WONTFIX SKIP : fast/events/message-port-no-wrapper.html = FAIL
WONTFIX SKIP : fast/events/message-port.html = FAIL
WONTFIX SKIP : fast/events/message-port-multi.html = FAIL
WONTFIX SKIP : http/tests/security/MessagePort/event-listener-context.html = FAIL
+WONTFIX SKIP : inspector/extensions.html = FAIL
// Implement java testing harness.
BUG36681 DEFER SKIP : java = TEXT
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 9cf734a..0c4e6ab 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,115 @@
+2010-08-02 Andrey Kosyakov <caseq at chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: adding experimental support for WebInspector extensions API.
+ https://bugs.webkit.org/show_bug.cgi?id=40425
+
+ Tests: inspector/extensions-api.html
+ inspector/extensions.html
+
+ * WebCore.gypi:
+ * WebCore.vcproj/WebCore.vcproj:
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::inspectedWindowScriptObjectCleared):
+ (WebCore::InspectorController::didCommitLoad):
+ * inspector/InspectorFrontendHost.cpp:
+ (WebCore::InspectorFrontendHost::setExtensionAPI):
+ * inspector/InspectorFrontendHost.h:
+ * inspector/InspectorFrontendHost.idl:
+ * inspector/front-end/ElementsPanel.js:
+ (WebInspector.ElementsPanel.this.treeOutline.focusedNodeChanged):
+ (WebInspector.ElementsPanel):
+ * inspector/front-end/ExtensionAPI.js: Added. An API implementation that gets injected into the extension context.
+ (injectedExtensionAPI):
+ (injectedExtensionAPI.EventSinkImpl.prototype.addListener):
+ (injectedExtensionAPI.EventSinkImpl.prototype.removeListener):
+ (injectedExtensionAPI.EventSinkImpl.prototype._fire):
+ (injectedExtensionAPI.EventSink):
+ (injectedExtensionAPI.InspectorExtensionAPI):
+ (injectedExtensionAPI.InspectorExtensionAPI.prototype.log):
+ (injectedExtensionAPI.Resources.prototype.getAll):
+ (injectedExtensionAPI.Resources.prototype.get return):
+ (injectedExtensionAPI.Resources.prototype):
+ (injectedExtensionAPI.Panels):
+ (injectedExtensionAPI.Panels.prototype.create.callbackWrapper):
+ (injectedExtensionAPI.Panels.prototype.create):
+ (injectedExtensionAPI.PanelImpl):
+ (injectedExtensionAPI.PanelImpl.prototype.createSidebarPane.callbackWrapper):
+ (injectedExtensionAPI.PanelImpl.prototype.createSidebarPane):
+ (injectedExtensionAPI.ExtensionPanel):
+ (injectedExtensionAPI.ExtensionSidebarPaneImpl):
+ (injectedExtensionAPI.ExtensionSidebarPaneImpl.prototype.setHeight):
+ (injectedExtensionAPI.ExtensionSidebarPaneImpl.prototype.setExpanded):
+ (injectedExtensionAPI.InspectedWindow):
+ (injectedExtensionAPI.InspectedWindow.prototype.reload):
+ (injectedExtensionAPI.InspectedWindow.prototype.evaluate):
+ (injectedExtensionAPI.ExtensionServerClient.prototype.sendRequest):
+ (injectedExtensionAPI.ExtensionServerClient.prototype.registerHandler):
+ (injectedExtensionAPI.ExtensionServerClient.prototype.nextObjectId):
+ (injectedExtensionAPI.ExtensionServerClient.prototype._registerCallback):
+ (injectedExtensionAPI.ExtensionServerClient.prototype._onCallback):
+ (injectedExtensionAPI.ExtensionServerClient.prototype._onMessage):
+ (injectedExtensionAPI.expandURL):
+ (injectedExtensionAPI.):
+ * inspector/front-end/ExtensionPanel.js: Added. A class that provides WebInspector's Panel interface to the inspector, hosts extension panel within an IFrame and proxies Panel callbacks to the extension.
+ (WebInspector.ExtensionPanel):
+ (WebInspector.ExtensionPanel.prototype.get defaultFocusedElement):
+ (WebInspector.ExtensionPanel.prototype.updateMainViewWidth):
+ (WebInspector.ExtensionPanel.prototype.searchCanceled):
+ (WebInspector.ExtensionPanel.prototype.performSearch):
+ (WebInspector.ExtensionPanel.prototype.jumpToNextSearchResult):
+ (WebInspector.ExtensionPanel.prototype.jumpToPreviousSearchResult):
+ (WebInspector.ExtensionPanel.prototype._addStyleRule):
+ * inspector/front-end/ExtensionRegistryStub.js: Added. A stub for ExtensionRegistry class that is meant to provide a list of extensions. Actual implementations may be browser-specfic.
+ (.WebInspector.InspectorExtensionRegistryStub):
+ (.WebInspector.InspectorExtensionRegistryStub.prototype.getExtensionsAsync):
+ * inspector/front-end/ExtensionServer.js: Added. Communicates with ExtensionAPI via DOM messaging and proxies requests to WebInspector classes.
+ (WebInspector.ExtensionServer):
+ (WebInspector.ExtensionServer.prototype.notifyPanelShown):
+ (WebInspector.ExtensionServer.prototype.notifyObjectSelected):
+ (WebInspector.ExtensionServer.prototype.notifyResourceFinished):
+ (WebInspector.ExtensionServer.prototype.notifySearchAction):
+ (WebInspector.ExtensionServer.prototype.notifyInspectedPageLoaded):
+ (WebInspector.ExtensionServer.prototype.notifyInspectedURLChanged):
+ (WebInspector.ExtensionServer.prototype.notifyInspectorReset):
+ (WebInspector.ExtensionServer.prototype._convertResource):
+ (WebInspector.ExtensionServer.prototype._postNotification):
+ (WebInspector.ExtensionServer.prototype._onSubscribe):
+ (WebInspector.ExtensionServer.prototype._onUnsubscribe):
+ (WebInspector.ExtensionServer.prototype._onCreatePanel):
+ (WebInspector.ExtensionServer.prototype._onCreateSidebar):
+ (WebInspector.ExtensionServer.prototype._createClientIframe):
+ (WebInspector.ExtensionServer.prototype._onSetSidebarHeight):
+ (WebInspector.ExtensionServer.prototype._onSetSidebarExpansion):
+ (WebInspector.ExtensionServer.prototype._onLog):
+ (WebInspector.ExtensionServer.prototype._onEvaluateOnInspectedPage):
+ (WebInspector.ExtensionServer.prototype._onRevealAndSelect):
+ (WebInspector.ExtensionServer.prototype._onRevealAndSelectResource):
+ (WebInspector.ExtensionServer.prototype._dispatchCallback):
+ (WebInspector.ExtensionServer.prototype._onGetResources):
+ (WebInspector.ExtensionServer.prototype.initExtensions):
+ (WebInspector.ExtensionServer.prototype._addExtensions):
+ (WebInspector.ExtensionServer.prototype._onWindowMessage):
+ (WebInspector.ExtensionServer.prototype._onmessage):
+ (WebInspector.ExtensionServer.prototype._registerHandler):
+ (WebInspector.ExtensionStatus):
+ (WebInspector.addExtensions):
+ * inspector/front-end/InjectedScript.js:
+ (injectedScriptConstructor):
+ * inspector/front-end/InjectedScriptAccess.js:
+ * inspector/front-end/InspectorFrontendHostStub.js:
+ (.WebInspector.InspectorFrontendHostStub.prototype.setExtensionAPI):
+ (.WebInspector.InspectorFrontendHostStub.prototype.canAttachWindow):
+ * inspector/front-end/WebKit.qrc:
+ * inspector/front-end/inspector.html:
+ * inspector/front-end/inspector.js:
+ (WebInspector.loaded):
+ (WebInspector.updateResource):
+ (WebInspector.reset):
+ (WebInspector.inspectedURLChanged):
+ (WebInspector.didCommitLoad):
+
2010-08-02 Ilya Tikhonovsky <loislo at chromium.org>
Reviewed by Yury Semikhatsky.
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index 7bbffe2..20482bb 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -4055,6 +4055,10 @@
'inspector/front-end/ElementsPanel.js',
'inspector/front-end/ElementsTreeOutline.js',
'inspector/front-end/EventListenersSidebarPane.js',
+ 'inspector/front-end/ExtensionAPI.js',
+ 'inspector/front-end/ExtensionPanel.js',
+ 'inspector/front-end/ExtensionRegistryStub.js',
+ 'inspector/front-end/ExtensionServer.js',
'inspector/front-end/FontView.js',
'inspector/front-end/HAREntry.js',
'inspector/front-end/HelpScreen.js',
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index 817746f..32220a0 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -50912,6 +50912,22 @@
>
</File>
<File
+ RelativePath="..\inspector\front-end\ExtensionAPI.js"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\front-end\ExtensionPanel.js"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\front-end\ExtensionRegistryStub.js"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\front-end\ExtensionServer.js"
+ >
+ </File>
+ <File
RelativePath="..\inspector\front-end\FontView.js"
>
</File>
diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp
index e29c7ae..369b40b 100644
--- a/WebCore/inspector/InspectorController.cpp
+++ b/WebCore/inspector/InspectorController.cpp
@@ -458,9 +458,18 @@ void InspectorController::inspectedWindowScriptObjectCleared(Frame* frame)
if (m_inspectorFrontendClient && frame == m_inspectedPage->mainFrame())
m_inspectorFrontendClient->windowObjectCleared();
- if (!enabled() || !m_frontend || frame != m_inspectedPage->mainFrame())
+ if (!enabled())
return;
- m_injectedScriptHost->discardInjectedScripts();
+
+ if (m_frontend && frame != m_inspectedPage->mainFrame())
+ m_injectedScriptHost->discardInjectedScripts();
+ if (m_scriptsToEvaluateOnLoad.size()) {
+ ScriptState* scriptState = mainWorldScriptState(frame);
+ for (Vector<String>::iterator it = m_scriptsToEvaluateOnLoad.begin();
+ it != m_scriptsToEvaluateOnLoad.end(); ++it) {
+ m_injectedScriptHost->injectScript(*it, scriptState);
+ }
+ }
}
void InspectorController::setSearchingForNode(bool enabled)
@@ -802,14 +811,6 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
for (Frame* frame = loader->frame(); frame; frame = frame->tree()->traverseNext(loader->frame()))
if (ResourcesMap* resourceMap = m_frameResources.get(frame))
pruneResources(resourceMap, loader);
-
- if (m_scriptsToEvaluateOnLoad.size()) {
- ScriptState* scriptState = mainWorldScriptState(loader->frame());
- for (Vector<String>::iterator it = m_scriptsToEvaluateOnLoad.begin();
- it != m_scriptsToEvaluateOnLoad.end(); ++it) {
- m_injectedScriptHost->injectScript(*it, scriptState);
- }
- }
}
void InspectorController::frameDetachedFromParent(Frame* frame)
diff --git a/WebCore/inspector/InspectorFrontendHost.cpp b/WebCore/inspector/InspectorFrontendHost.cpp
index 6957dd1..0dacde6 100644
--- a/WebCore/inspector/InspectorFrontendHost.cpp
+++ b/WebCore/inspector/InspectorFrontendHost.cpp
@@ -192,6 +192,14 @@ void InspectorFrontendHost::moveWindowBy(float x, float y) const
m_client->moveWindowBy(x, y);
}
+void InspectorFrontendHost::setExtensionAPI(const String& script)
+{
+ InspectorController* inspector = m_frontendPage->inspectorController();
+
+ inspector->removeAllScriptsToEvaluateOnLoad();
+ inspector->addScriptToEvaluateOnLoad(script);
+}
+
String InspectorFrontendHost::localizedStringsURL()
{
return m_client->localizedStringsURL();
diff --git a/WebCore/inspector/InspectorFrontendHost.h b/WebCore/inspector/InspectorFrontendHost.h
index 7fb4a1e..4b343fd 100644
--- a/WebCore/inspector/InspectorFrontendHost.h
+++ b/WebCore/inspector/InspectorFrontendHost.h
@@ -67,6 +67,7 @@ public:
void setAttachedWindowHeight(unsigned height);
void moveWindowBy(float x, float y) const;
+ void setExtensionAPI(const String& script);
String localizedStringsURL();
String hiddenPanels();
diff --git a/WebCore/inspector/InspectorFrontendHost.idl b/WebCore/inspector/InspectorFrontendHost.idl
index d1b3604..0c7cf8b 100644
--- a/WebCore/inspector/InspectorFrontendHost.idl
+++ b/WebCore/inspector/InspectorFrontendHost.idl
@@ -41,6 +41,7 @@ module core {
void requestDetachWindow();
void setAttachedWindowHeight(in unsigned long height);
void moveWindowBy(in float x, in float y);
+ void setExtensionAPI(in DOMString script);
DOMString localizedStringsURL();
DOMString hiddenPanels();
diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js
index 557a8bd..09a84f7 100644
--- a/WebCore/inspector/front-end/ElementsPanel.js
+++ b/WebCore/inspector/front-end/ElementsPanel.js
@@ -56,8 +56,10 @@ WebInspector.ElementsPanel = function()
this.panel.updateProperties();
this.panel.updateEventListeners();
- if (this._focusedDOMNode)
+ if (this._focusedDOMNode) {
InspectorBackend.addInspectedNode(this._focusedDOMNode.id);
+ WebInspector.extensionServer.notifyObjectSelected(this.name, "DOMNode");
+ }
};
this.contentElement.appendChild(this.treeOutline.element);
diff --git a/WebCore/inspector/front-end/ExtensionAPI.js b/WebCore/inspector/front-end/ExtensionAPI.js
new file mode 100644
index 0000000..476a463
--- /dev/null
+++ b/WebCore/inspector/front-end/ExtensionAPI.js
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+var injectedExtensionAPI = function(InjectedScriptHost, inspectedWindow, injectedScriptId)
+{
+
+// Here and below, all constructors are private to API implementation.
+// For a public type Foo, if internal fields are present, these are on
+// a private FooImpl type, an instance of FooImpl is used in a closure
+// by Foo consutrctor to re-bind publicly exported members to an instance
+// of Foo.
+
+function EventSinkImpl(type)
+{
+ this._type = type;
+ this._listeners = [];
+}
+
+EventSinkImpl.prototype = {
+ addListener: function(callback)
+ {
+ if (this._listeners.length === 0)
+ extensionServer.sendRequest({ command: "subscribe", type: this._type });
+ this._listeners.push(callback);
+ extensionServer.registerHandler("notify-" + this._type, bind(this._fire, this));
+ },
+
+ removeListener: function(callback)
+ {
+ var listeners = this._listeners;
+
+ for (var i = 0; i < listeners.length; ++i) {
+ if (listeners[i] === callback) {
+ listeners.splice(i, 1);
+ break;
+ }
+ }
+ if (this._listeners.length === 0)
+ extensionServer.sendRequest({ command: "unsubscribe", type: this._type });
+ },
+
+ _fire: function(request)
+ {
+ var listeners = this._listeners.slice();
+ for (var i = 0; i < listeners.length; ++i)
+ listeners[i].apply(null, request.arguments);
+ }
+}
+
+function EventSink(type)
+{
+ var impl = new EventSinkImpl(type);
+ this.addListener = bind(impl.addListener, impl);
+ this.removeListener = bind(impl.removeListener, impl);
+}
+
+function InspectorExtensionAPI()
+{
+ this.inspectedWindow = new InspectedWindow();
+ this.panels = new Panels();
+ this.resources = new Resources();
+ this.onReset = new EventSink("reset");
+}
+
+InspectorExtensionAPI.prototype = {
+ log: function(message)
+ {
+ extensionServer.sendRequest({ command: "log", message: message });
+ }
+}
+
+function Resources()
+{
+ this.onFinished = new EventSink("resource-finished");
+}
+
+Resources.prototype = {
+ getAll: function(callback)
+ {
+ return extensionServer.sendRequest({ command: "getResources" }, callback);
+ },
+
+ get: function(id, callback)
+ {
+ return extensionServer.sendRequest({ command: "getResources", id: id }, callback);
+ }
+}
+
+var wellKnownPanelNames = [
+ "elements",
+ "scripts"
+];
+
+function Panels()
+{
+ var panels = [];
+ function panelGetter(name)
+ {
+ return panels[name];
+ }
+
+ for (var i = 0; i < wellKnownPanelNames.length; ++i) {
+ var name = wellKnownPanelNames[i];
+ panels[name] = new Panel(name);
+ this.__defineGetter__(name, bind(panelGetter, null, name));
+ }
+}
+
+Panels.prototype = {
+ create: function(label, pageURL, iconURL, callback)
+ {
+ var id = "extension-panel-" + extensionServer.nextObjectId();
+ function callbackWrapper(result)
+ {
+ if (result.isError)
+ callback(result);
+ else {
+ panel = new ExtensionPanel(id);
+ callback(panel);
+ }
+ }
+ var request = {
+ command: "createPanel",
+ id: id,
+ label: label,
+ url: expandURL(pageURL),
+ icon: expandURL(iconURL)
+ };
+ extensionServer.sendRequest(request, callback && bind(callbackWrapper, this));
+ }
+}
+
+function PanelImpl(id)
+{
+ this._id = id;
+ this.onSelectionChanged = new EventSink("panel-objectSelected-" + id);
+}
+
+PanelImpl.prototype = {
+ createSidebarPane: function(title, url, callback)
+ {
+ var id = "extension-sidebar-" + extensionServer.nextObjectId();
+ function callbackWrapper(result)
+ {
+ if (result.isError)
+ callback(result);
+ else
+ callback(new ExtensionSidebarPane(id));
+ }
+ extensionServer.sendRequest({ command: "createSidebarPane", panel: this._id, id: id, title: title, url: expandURL(url) }, callback && callbackWrapper);
+ }
+}
+
+function Panel(id)
+{
+ var impl = new PanelImpl(id);
+ this.createSidebarPane = bind(impl.createSidebarPane, impl);
+}
+
+function ExtensionPanel(id)
+{
+ Panel.call(this, id);
+ this.onSearch = new EventSink("panel-search-" + id);
+}
+
+ExtensionPanel.prototype = {
+}
+
+ExtensionPanel.prototype.__proto__ = Panel.prototype;
+
+function ExtensionSidebarPaneImpl(id)
+{
+ this._id = id;
+}
+
+ExtensionSidebarPaneImpl.prototype = {
+ setHeight: function(height)
+ {
+ extensionServer.sendRequest({ command: "setSidebarHeight", id: this._id, height: height });
+ },
+
+ setExpanded: function(expanded)
+ {
+ extensionServer.sendRequest({ command: "setSidebarExpanded", id: this._id, expanded: expanded });
+ }
+}
+
+function ExtensionSidebarPane(id)
+{
+ var impl = new ExtensionSidebarPaneImpl(id);
+ this.setHeight = bind(impl.setHeight, impl);
+ this.setExpanded = bind(impl.setExpanded, impl);
+}
+
+function InspectedWindow()
+{
+ this.onLoaded = new EventSink("inspectedPageLoaded");
+ this.onNavigated = new EventSink("inspectedURLChanged");
+ this.onDOMContentLoaded = new EventSink("DOMContentLoaded");
+}
+
+InspectedWindow.prototype = {
+ reload: function()
+ {
+ return extensionServer.sendRequest({ command: "reload" });
+ },
+
+ evaluate: function(expression, callback)
+ {
+ return extensionServer.sendRequest({ command: "evaluateOnInspectedPage", expression: expression }, callback);
+ }
+}
+
+function ExtensionServerClient()
+{
+ this._callbacks = {};
+ this._handlers = {};
+ this._lastRequestId = 0;
+ this._lastObjectId = 0;
+
+ this.registerHandler("callback", bind(this._onCallback, this));
+
+ var channel = new MessageChannel();
+ this._port = channel.port1;
+ this._port.addEventListener("message", bind(this._onMessage, this), false);
+ this._port.start();
+
+ top.postMessage("registerExtension", [ channel.port2 ], "*");
+}
+
+ExtensionServerClient.prototype = {
+ sendRequest: function(message, callback)
+ {
+ if (typeof callback === "function")
+ message.requestId = this._registerCallback(callback);
+ return this._port.postMessage(message);
+ },
+
+ registerHandler: function(command, handler)
+ {
+ this._handlers[command] = handler;
+ },
+
+ nextObjectId: function()
+ {
+ return injectedScriptId + "_" + ++this._lastObjectId;
+ },
+
+ _registerCallback: function(callback)
+ {
+ var id = ++this._lastRequestId;
+ this._callbacks[id] = callback;
+ return id;
+ },
+
+ _onCallback: function(request)
+ {
+ if (request.requestId in this._callbacks) {
+ this._callbacks[request.requestId](request.result);
+ delete this._callbacks[request.requestId];
+ }
+ },
+
+ _onMessage: function(event)
+ {
+ var request = event.data;
+ var handler = this._handlers[request.command];
+ if (handler)
+ handler.call(this, request);
+ }
+}
+
+function expandURL(url)
+{
+ if (!url)
+ return url;
+ if (/^[^/]+:/.exec(url)) // See if url has schema.
+ return url;
+ var baseURL = location.protocol + "//" + location.hostname + location.port;
+ if (/^\//.exec(url))
+ return baseURL + url;
+ return baseURL + location.pathname.replace(/\/[^/]*$/,"/") + url;
+}
+
+function bind(func, thisObject)
+{
+ var args = Array.prototype.slice.call(arguments, 2);
+ return function() { return func.apply(thisObject, args.concat(Array.prototype.slice.call(arguments, 0))); };
+}
+
+var extensionServer = new ExtensionServerClient();
+
+webInspector = new InspectorExtensionAPI();
+
+}
diff --git a/WebCore/inspector/front-end/ExtensionPanel.js b/WebCore/inspector/front-end/ExtensionPanel.js
new file mode 100644
index 0000000..ba5fa8e
--- /dev/null
+++ b/WebCore/inspector/front-end/ExtensionPanel.js
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.ExtensionPanel = function(id, label, iconURL, options)
+{
+ this.toolbarItemLabel = label;
+ this._addStyleRule(".toolbar-item." + id + " .toolbar-icon", "background-image: url(" + iconURL + ");");
+ WebInspector.Panel.call(this, id);
+}
+
+WebInspector.ExtensionPanel.prototype = {
+ get defaultFocusedElement()
+ {
+ return this.sidebarTreeElement || this.element;
+ },
+
+ updateMainViewWidth: function(width)
+ {
+ this.bodyElement.style.left = width + "px";
+ this.resize();
+ },
+
+ searchCanceled: function(startingNewSearch)
+ {
+ WebInspector.extensionServer.notifySearchAction(this._id, "cancelSearch");
+ WebInspector.Panel.prototype.searchCanceled.apply(this, arguments);
+ },
+
+ performSearch: function(query)
+ {
+ WebInspector.extensionServer.notifySearchAction(this._id, "performSearch", query);
+ WebInspector.Panel.prototype.performSearch.apply(this, arguments);
+ },
+
+ jumpToNextSearchResult: function()
+ {
+ WebInspector.extensionServer.notifySearchAction(this._id, "nextSearchResult");
+ WebInspector.Panel.prototype.jumpToNextSearchResult.call(this);
+ },
+
+ jumpToPreviousSearchResult: function()
+ {
+ WebInspector.extensionServer.notifySearchAction(this._id, "previousSearchResult");
+ WebInspector.Panel.prototype.jumpToPreviousSearchResult.call(this);
+ },
+
+ _addStyleRule: function(selector, body)
+ {
+ var style = document.createElement("style");
+ style.textContent = selector + " { " + body + " }";
+ document.head.appendChild(style);
+ }
+}
+
+WebInspector.ExtensionPanel.prototype.__proto__ = WebInspector.Panel.prototype;
diff --git a/WebCore/inspector/front-end/ExtensionRegistryStub.js b/WebCore/inspector/front-end/ExtensionRegistryStub.js
new file mode 100644
index 0000000..a9c96ef
--- /dev/null
+++ b/WebCore/inspector/front-end/ExtensionRegistryStub.js
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+if (!window.InspectorExtensionRegistry) {
+
+WebInspector.InspectorExtensionRegistryStub = function()
+{
+}
+
+WebInspector.InspectorExtensionRegistryStub.prototype = {
+ getExtensionsAsync: function()
+ {
+ }
+};
+
+InspectorExtensionRegistry = new WebInspector.InspectorExtensionRegistryStub();
+
+}
diff --git a/WebCore/inspector/front-end/ExtensionServer.js b/WebCore/inspector/front-end/ExtensionServer.js
new file mode 100644
index 0000000..2d2eab1
--- /dev/null
+++ b/WebCore/inspector/front-end/ExtensionServer.js
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.ExtensionServer = function()
+{
+ this._clientObjects = {};
+ this._handlers = {};
+ this._subscribers = {};
+ this._status = new WebInspector.ExtensionStatus();
+
+ this._registerHandler("subscribe", this._onSubscribe.bind(this));
+ this._registerHandler("unsubscribe", this._onUnsubscribe.bind(this));
+ this._registerHandler("getResources", this._onGetResources.bind(this));
+ this._registerHandler("createPanel", this._onCreatePanel.bind(this));
+ this._registerHandler("createSidebarPane", this._onCreateSidebar.bind(this));
+ this._registerHandler("log", this._onLog.bind(this));
+ this._registerHandler("evaluateOnInspectedPage", this._onEvaluateOnInspectedPage.bind(this));
+ this._registerHandler("setSidebarHeight", this._onSetSidebarHeight.bind(this));
+ this._registerHandler("setSidebarExpanded", this._onSetSidebarExpansion.bind(this));
+
+ window.addEventListener("message", this._onWindowMessage.bind(this), false);
+}
+
+WebInspector.ExtensionServer.prototype = {
+ notifyPanelShown: function(panelName)
+ {
+ this._postNotification("panel-shown-" + panelName);
+ },
+
+ notifyObjectSelected: function(panelId, objectType, objectId)
+ {
+ this._postNotification("panel-objectSelected-" + panelId, objectType, objectId);
+ },
+
+ notifyResourceFinished: function(resource)
+ {
+ this._postNotification("resource-finished", this._convertResource(resource));
+ },
+
+ notifySearchAction: function(panelId, action, searchString)
+ {
+ this._postNotification("panel-search-" + panelId, action, searchString);
+ },
+
+ notifyInspectedPageLoaded: function()
+ {
+ this._postNotification("inspectedPageLoaded");
+ },
+
+ notifyInspectedURLChanged: function()
+ {
+ this._postNotification("inspectedURLChanged");
+ },
+
+ notifyInspectorReset: function()
+ {
+ this._postNotification("reset");
+ },
+
+ _convertResource: function(resource)
+ {
+ return {
+ id: resource.identifier,
+ type: resource.type,
+ har: (new WebInspector.HAREntry(resource)).build(),
+ };
+ },
+
+ _postNotification: function(type, details)
+ {
+ var subscribers = this._subscribers[type];
+ if (!subscribers)
+ return;
+ var message = {
+ command: "notify-" + type,
+ arguments: Array.prototype.slice.call(arguments, 1)
+ };
+ for (var i = 0; i < subscribers.length; ++i)
+ subscribers[i].postMessage(message);
+ },
+
+ _onSubscribe: function(message, port)
+ {
+ var subscribers = this._subscribers[message.type];
+ if (subscribers)
+ subscribers.push(port);
+ else
+ this._subscribers[message.type] = [ port ];
+ },
+
+ _onUnsubscribe: function(message, port)
+ {
+ var subscribers = this._subscribers[message.type];
+ if (!subscribers)
+ return;
+ subscribers.remove(port);
+ if (!subscribers.length)
+ delete this._subscribers[message.type];
+ },
+
+ _onCreatePanel: function(message, port)
+ {
+ var id = message.id;
+ // The ids are generated on the client API side and must be unique, so the check below
+ // shouldn't be hit unless someone is bypassing the API.
+ if (id in this._clientObjects || id in WebInspector.panels)
+ return this._status.E_EXISTS(id);
+ var panel = new WebInspector.ExtensionPanel(id, message.label, message.icon);
+ this._clientObjects[id] = panel;
+
+ var toolbarElement = document.getElementById("toolbar");
+ var lastToolbarItem = WebInspector.panelOrder[WebInspector.panelOrder.length - 1].toolbarItem;
+ WebInspector.addPanelToolbarIcon(toolbarElement, panel, lastToolbarItem);
+ WebInspector.panels[id] = panel;
+ this._createClientIframe(panel.element, message.url);
+ return this._status.OK();
+ },
+
+ _onCreateSidebar: function(message, port)
+ {
+ var panel = WebInspector.panels[message.panel];
+ if (!panel)
+ return this._status.E_NOTFOUND(message.panel);
+ if (!panel.sidebarElement || !panel.sidebarPanes)
+ return this._status.E_NOTSUPPORTED();
+ var id = message.id;
+ var sidebar = new WebInspector.SidebarPane(message.title);
+ this._clientObjects[id] = sidebar;
+ panel.sidebarPanes[id] = sidebar;
+ panel.sidebarElement.appendChild(sidebar.element);
+ this._createClientIframe(sidebar.bodyElement, message.url);
+ return this._status.OK();
+ },
+
+ _createClientIframe: function(parent, url, requestId, port)
+ {
+ var iframe = document.createElement("iframe");
+ iframe.src = url;
+ iframe.style.width = "100%";
+ parent.appendChild(iframe);
+ },
+
+ _onSetSidebarHeight: function(message)
+ {
+ var sidebar = this._clientObjects[message.id];
+ if (!sidebar)
+ return this._status.E_NOTFOUND(message.id);
+ sidebar.bodyElement.firstChild.style.height = message.height;
+ },
+
+ _onSetSidebarExpansion: function(message)
+ {
+ var sidebar = this._clientObjects[message.id];
+ if (!sidebar)
+ return this._status.E_NOTFOUND(message.id);
+ if (message.expanded)
+ sidebar.expand();
+ else
+ sidebar.collapse();
+ },
+
+ _onLog: function(message)
+ {
+ WebInspector.log(message.message);
+ },
+
+ _onEvaluateOnInspectedPage: function(message, port)
+ {
+ InjectedScriptAccess.getDefault().evaluateAndStringify(message.expression, this._dispatchCallback.bind(this, message.requestId, port));
+ },
+
+ _onRevealAndSelect: function(message)
+ {
+ if (message.panelId === "resources" && type === "resource")
+ return this._onRevealAndSelectResource(message);
+ else
+ return this._status.E_NOTSUPPORTED(message.panelId, message.type);
+ },
+
+ _onRevealAndSelectResource: function(message)
+ {
+ var id = message.id;
+ var resource = null;
+
+ resource = typeof id === "number" ? WebInspector.resources[id] : WebInspector.resourceForURL(id);
+ if (!resource)
+ return this._status.E_NOTFOUND(typeof id + ": " + id);
+ WebInspector.panels.resources.showResource(resource, message.line);
+ WebInspector.showResourcesPanel();
+ },
+
+ _dispatchCallback: function(requestId, port, result)
+ {
+ port.postMessage({ command: "callback", requestId: requestId, result: result });
+ },
+
+ _onGetResources: function(request)
+ {
+ function resourceWrapper(id)
+ {
+ return WebInspector.extensionServer._convertResource(WebInspector.resources[id]);
+ }
+
+ var response;
+ if (request.id)
+ response = WebInspector.resources[request.id] ? resourceWrapper(request.id) : this._status.E_NOTFOUND(request.id);
+ else
+ response = Object.properties(WebInspector.resources).map(resourceWrapper);
+ return response;
+ },
+
+ initExtensions: function()
+ {
+ InspectorExtensionRegistry.getExtensionsAsync();
+ },
+
+ _addExtensions: function(extensions)
+ {
+ InspectorFrontendHost.setExtensionAPI("(" + injectedExtensionAPI.toString() + ")"); // See ExtensionAPI.js for details.
+ for (var i = 0; i < extensions.length; ++i) {
+ var extension = extensions[i];
+ try {
+ if (!extension.startPage)
+ return;
+ var iframe = document.createElement("iframe");
+ iframe.src = extension.startPage;
+ iframe.style.display = "none";
+ document.body.appendChild(iframe);
+ } catch (e) {
+ console.error("Failed to initialize extension " + extension.startPage + ":" + e);
+ }
+ }
+ },
+
+ _onWindowMessage: function(event)
+ {
+ if (event.data !== "registerExtension")
+ return;
+ var port = event.ports[0];
+ port.addEventListener("message", this._onmessage.bind(this), false);
+ port.start();
+ },
+
+ _onmessage: function(event)
+ {
+ var request = event.data;
+ var result;
+
+ if (request.command in this._handlers)
+ result = this._handlers[request.command](request, event.target);
+ else
+ result = this._status.E_NOTSUPPORTED(request.command);
+
+ if (result && request.requestId)
+ this._dispatchCallback(request.requestId, event.target, result);
+ },
+
+ _registerHandler: function(command, callback)
+ {
+ this._handlers[command] = callback;
+ }
+}
+
+WebInspector.ExtensionServer._statuses =
+{
+ OK: "",
+ E_NOTFOUND: "Object not found (%s)",
+ E_NOTSUPPORTED: "Object does not support requested operation (%s)",
+ E_EXISTS: "Object already exists (%s)"
+}
+
+WebInspector.ExtensionStatus = function()
+{
+ function makeStatus(code)
+ {
+ var description = WebInspector.ExtensionServer._statuses[code] || code;
+ var details = Array.prototype.slice.call(arguments, 1);
+ var status = { code: code, description: description, details: details };
+ if (code !== "OK") {
+ status.isError = true;
+ console.log("Extension server error: " + String.vsprintf(description, details));
+ }
+ return status;
+ }
+ for (status in WebInspector.ExtensionServer._statuses)
+ this[status] = makeStatus.bind(null, status);
+}
+
+WebInspector.addExtensions = function(extensions)
+{
+ WebInspector.extensionServer._addExtensions(extensions);
+}
diff --git a/WebCore/inspector/front-end/InjectedScript.js b/WebCore/inspector/front-end/InjectedScript.js
index ce187d2..3a114c0 100644
--- a/WebCore/inspector/front-end/InjectedScript.js
+++ b/WebCore/inspector/front-end/InjectedScript.js
@@ -238,6 +238,19 @@ InjectedScript.getCompletions = function(expression, includeInspectorCommandLine
return props;
}
+InjectedScript.evaluateAndStringify = function(expression)
+{
+ var result = {};
+ try {
+ var value = InjectedScript._evaluateOn(inspectedWindow.eval, inspectedWindow, expression, false);
+ result.value = JSON.stringify(value);
+ } catch (e) {
+ result.value = e.toString();
+ result.isException = true;
+ }
+ return result;
+}
+
InjectedScript.evaluate = function(expression, objectGroup)
{
return InjectedScript._evaluateAndWrap(inspectedWindow.eval, inspectedWindow, expression, objectGroup);
diff --git a/WebCore/inspector/front-end/InjectedScriptAccess.js b/WebCore/inspector/front-end/InjectedScriptAccess.js
index 5950421..59aa70c 100644
--- a/WebCore/inspector/front-end/InjectedScriptAccess.js
+++ b/WebCore/inspector/front-end/InjectedScriptAccess.js
@@ -75,14 +75,15 @@ InjectedScriptAccess._installHandler = function(methodName, async)
// - Make sure last parameter of all the InjectedSriptAccess.* calls is a callback function.
// We keep these sorted.
InjectedScriptAccess._installHandler("evaluate");
+InjectedScriptAccess._installHandler("evaluateAndStringify");
InjectedScriptAccess._installHandler("evaluateInCallFrame");
+InjectedScriptAccess._installHandler("evaluateOnSelf");
InjectedScriptAccess._installHandler("getCompletions");
InjectedScriptAccess._installHandler("getProperties");
InjectedScriptAccess._installHandler("getPrototypes");
InjectedScriptAccess._installHandler("openInInspectedWindow");
InjectedScriptAccess._installHandler("pushNodeToFrontend");
InjectedScriptAccess._installHandler("setPropertyValue");
-InjectedScriptAccess._installHandler("evaluateOnSelf");
// Some methods can't run synchronously even on the injected script side (such as DB transactions).
// Mark them as asynchronous here.
diff --git a/WebCore/inspector/front-end/InspectorFrontendHostStub.js b/WebCore/inspector/front-end/InspectorFrontendHostStub.js
index c771967..c4e6bf4 100644
--- a/WebCore/inspector/front-end/InspectorFrontendHostStub.js
+++ b/WebCore/inspector/front-end/InspectorFrontendHostStub.js
@@ -84,6 +84,10 @@ WebInspector.InspectorFrontendHostStub.prototype = {
{
},
+ setExtensionAPI: function(script)
+ {
+ },
+
loaded: function()
{
},
diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc
index 42ad915..a54936c 100644
--- a/WebCore/inspector/front-end/WebKit.qrc
+++ b/WebCore/inspector/front-end/WebKit.qrc
@@ -34,6 +34,10 @@
<file>ElementsPanel.js</file>
<file>ElementsTreeOutline.js</file>
<file>EventListenersSidebarPane.js</file>
+ <file>ExtensionAPI.js</file>
+ <file>ExtensionPanel.js</file>
+ <file>ExtensionRegistryStub.js</file>
+ <file>ExtensionServer.js</file>
<file>FontView.js</file>
<file>HAREntry.js</file>
<file>HelpScreen.js</file>
diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html
index c829195..48e95bb 100644
--- a/WebCore/inspector/front-end/inspector.html
+++ b/WebCore/inspector/front-end/inspector.html
@@ -39,6 +39,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="inspector.js"></script>
<script type="text/javascript" src="InspectorBackendStub.js"></script>
<script type="text/javascript" src="InspectorFrontendHostStub.js"></script>
+ <script type="text/javascript" src="ExtensionRegistryStub.js"></script>
<script type="text/javascript" src="Object.js"></script>
<script type="text/javascript" src="Settings.js"></script>
<script type="text/javascript" src="CSSStyleModel.js"></script>
@@ -96,6 +97,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="StoragePanel.js"></script>
<script type="text/javascript" src="ProfilesPanel.js"></script>
<script type="text/javascript" src="ConsolePanel.js"></script>
+ <script type="text/javascript" src="ExtensionAPI.js"></script>
+ <script type="text/javascript" src="ExtensionServer.js"></script>
+ <script type="text/javascript" src="ExtensionPanel.js"></script>
<script type="text/javascript" src="AuditsPanel.js"></script>
<script type="text/javascript" src="AuditResultView.js"></script>
<script type="text/javascript" src="AuditLauncherView.js"></script>
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index 0adf057..4bb30c7 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -526,6 +526,9 @@ WebInspector.loaded = function()
document.getElementById("close-button-left").addEventListener("click", this.close, true);
document.getElementById("close-button-right").addEventListener("click", this.close, true);
+ this.extensionServer = new WebInspector.ExtensionServer();
+ this.extensionServer.initExtensions();
+
InspectorFrontendHost.loaded();
}
@@ -1202,6 +1205,7 @@ WebInspector.updateResource = function(identifier, payload)
resource.finished = payload.finished;
if (this.panels.audits)
this.panels.audits.resourceFinished(resource);
+ this.extensionServer.notifyResourceFinished(resource);
}
if (payload.didTimingChange) {
@@ -1426,6 +1430,7 @@ WebInspector.reset = function()
delete this.mainResource;
this.console.clearMessages();
+ this.extensionServer.notifyInspectorReset();
}
WebInspector.resetProfilesPanel = function()
@@ -1442,6 +1447,7 @@ WebInspector.bringToFront = function()
WebInspector.inspectedURLChanged = function(url)
{
InspectorFrontendHost.inspectedURLChanged(url);
+ this.extensionServer.notifyInspectedURLChanged();
}
WebInspector.resourceURLChanged = function(resource, oldURL)
@@ -1454,6 +1460,7 @@ WebInspector.didCommitLoad = function()
{
// Cleanup elements panel early on inspected page refresh.
WebInspector.setDocument(null);
+ this.extensionServer.notifyInspectedPageLoaded();
}
WebInspector.updateConsoleMessageExpiredCount = function(count)
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list