summaryrefslogtreecommitdiffstats
path: root/Source/WebKit/chromium/src/js
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit/chromium/src/js')
-rw-r--r--Source/WebKit/chromium/src/js/DevTools.js190
-rwxr-xr-xSource/WebKit/chromium/src/js/Images/segmentChromium.pngbin0 -> 4272 bytes
-rwxr-xr-xSource/WebKit/chromium/src/js/Images/segmentHoverChromium.pngbin0 -> 4160 bytes
-rwxr-xr-xSource/WebKit/chromium/src/js/Images/segmentHoverEndChromium.pngbin0 -> 4143 bytes
-rwxr-xr-xSource/WebKit/chromium/src/js/Images/segmentSelectedChromium.pngbin0 -> 4113 bytes
-rwxr-xr-xSource/WebKit/chromium/src/js/Images/segmentSelectedEndChromium.pngbin0 -> 4104 bytes
-rwxr-xr-xSource/WebKit/chromium/src/js/Images/statusbarBackgroundChromium.pngbin0 -> 4116 bytes
-rwxr-xr-xSource/WebKit/chromium/src/js/Images/statusbarBottomBackgroundChromium.pngbin0 -> 4120 bytes
-rwxr-xr-xSource/WebKit/chromium/src/js/Images/statusbarButtonsChromium.pngbin0 -> 4313 bytes
-rwxr-xr-xSource/WebKit/chromium/src/js/Images/statusbarMenuButtonChromium.pngbin0 -> 4654 bytes
-rwxr-xr-xSource/WebKit/chromium/src/js/Images/statusbarMenuButtonSelectedChromium.pngbin0 -> 4372 bytes
-rw-r--r--Source/WebKit/chromium/src/js/Tests.js838
-rw-r--r--Source/WebKit/chromium/src/js/devTools.css117
13 files changed, 1145 insertions, 0 deletions
diff --git a/Source/WebKit/chromium/src/js/DevTools.js b/Source/WebKit/chromium/src/js/DevTools.js
new file mode 100644
index 0000000..d6536bc
--- /dev/null
+++ b/Source/WebKit/chromium/src/js/DevTools.js
@@ -0,0 +1,190 @@
+/*
+ * 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.
+ */
+
+/**
+ * FIXME: change field naming style to use trailing underscore.
+ * @fileoverview Tools is a main class that wires all components of the
+ * DevTools frontend together. It is also responsible for overriding existing
+ * WebInspector functionality while it is getting upstreamed into WebCore.
+ */
+
+var context = {}; // Used by WebCore's inspector routines.
+
+(function () {
+ Preferences.ignoreWhitespace = false;
+ Preferences.samplingCPUProfiler = true;
+ Preferences.heapProfilerPresent = true;
+ Preferences.debuggerAlwaysEnabled = true;
+ Preferences.profilerAlwaysEnabled = true;
+ Preferences.canEditScriptSource = true;
+ Preferences.onlineDetectionEnabled = false;
+ Preferences.nativeInstrumentationEnabled = true;
+ Preferences.fileSystemEnabled = false;
+ Preferences.resourceExportEnabled = true;
+ Preferences.showTimingTab = true;
+ Preferences.showCookiesTab = true;
+})();
+
+var devtools = devtools || {};
+
+devtools.domContentLoaded = function()
+{
+ WebInspector.setAttachedWindow(WebInspector.queryParamsObject.docked === "true");
+ if (WebInspector.queryParamsObject.toolbar_color && WebInspector.queryParamsObject.text_color)
+ WebInspector.setToolbarColors(WebInspector.queryParamsObject.toolbar_color, WebInspector.queryParamsObject.text_color);
+}
+document.addEventListener("DOMContentLoaded", devtools.domContentLoaded, false);
+
+
+// FIXME: This needs to be upstreamed.
+(function InterceptProfilesPanelEvents()
+{
+ var oldShow = WebInspector.ProfilesPanel.prototype.show;
+ WebInspector.ProfilesPanel.prototype.show = function()
+ {
+ this.enableToggleButton.visible = false;
+ oldShow.call(this);
+ // Show is called on every show event of a panel, so
+ // we only need to intercept it once.
+ WebInspector.ProfilesPanel.prototype.show = oldShow;
+ };
+})();
+
+
+/*
+ * @override
+ * TODO(mnaganov): Restore l10n when it will be agreed that it is needed.
+ */
+WebInspector.UIString = function(string)
+{
+ return String.vsprintf(string, Array.prototype.slice.call(arguments, 1));
+};
+
+
+/** Pending WebKit upstream by apavlov). Fixes iframe vs drag problem. */
+(function()
+{
+ var originalDragStart = WebInspector.elementDragStart;
+ WebInspector.elementDragStart = function(element)
+ {
+ if (element) {
+ var glassPane = document.createElement("div");
+ glassPane.style.cssText = "position:absolute;width:100%;height:100%;opacity:0;z-index:1";
+ glassPane.id = "glass-pane-for-drag";
+ element.parentElement.appendChild(glassPane);
+ }
+
+ originalDragStart.apply(this, arguments);
+ };
+
+ var originalDragEnd = WebInspector.elementDragEnd;
+ WebInspector.elementDragEnd = function()
+ {
+ originalDragEnd.apply(this, arguments);
+
+ var glassPane = document.getElementById("glass-pane-for-drag");
+ if (glassPane)
+ glassPane.parentElement.removeChild(glassPane);
+ };
+})();
+
+
+
+///////////////////////////////////////////
+// Chromium layout test harness support. //
+///////////////////////////////////////////
+
+WebInspector.runAfterPendingDispatchesQueue = [];
+
+WebInspector.TestController.prototype.runAfterPendingDispatches = function(callback)
+{
+ WebInspector.runAfterPendingDispatchesQueue.push(callback);
+};
+
+WebInspector.queuesAreEmpty = function()
+{
+ var copy = this.runAfterPendingDispatchesQueue.slice();
+ this.runAfterPendingDispatchesQueue = [];
+ for (var i = 0; i < copy.length; ++i)
+ copy[i].call(this);
+};
+
+
+/////////////////////////////
+// Chromium theme support. //
+/////////////////////////////
+
+WebInspector.setToolbarColors = function(backgroundColor, color)
+{
+ if (!WebInspector._themeStyleElement) {
+ WebInspector._themeStyleElement = document.createElement("style");
+ document.head.appendChild(WebInspector._themeStyleElement);
+ }
+ WebInspector._themeStyleElement.textContent =
+ "#toolbar {\
+ background-image: none !important;\
+ background-color: " + backgroundColor + " !important;\
+ }\
+ \
+ .toolbar-label {\
+ color: " + color + " !important;\
+ text-shadow: none;\
+ }";
+}
+
+WebInspector.resetToolbarColors = function()
+{
+ if (WebInspector._themeStyleElement)
+ WebInspector._themeStyleElement.textContent = "";
+
+}
+
+////////////////////////////////////////////////////////
+// Platform-specific WebInspector extensions support. //
+////////////////////////////////////////////////////////
+
+WebInspector.platformExtensionAPI = function(tabId)
+{
+ function getTabId()
+ {
+ return tabId;
+ }
+ webInspector.inspectedWindow.__proto__.__defineGetter__("tabId", getTabId);
+}
+
+WebInspector.buildPlatformExtensionAPI = function()
+{
+ return "(" + WebInspector.platformExtensionAPI + ")(" + WebInspector._inspectedTabId + ");";
+}
+
+WebInspector.setInspectedTabId = function(tabId)
+{
+ WebInspector._inspectedTabId = tabId;
+}
diff --git a/Source/WebKit/chromium/src/js/Images/segmentChromium.png b/Source/WebKit/chromium/src/js/Images/segmentChromium.png
new file mode 100755
index 0000000..f4248e1
--- /dev/null
+++ b/Source/WebKit/chromium/src/js/Images/segmentChromium.png
Binary files differ
diff --git a/Source/WebKit/chromium/src/js/Images/segmentHoverChromium.png b/Source/WebKit/chromium/src/js/Images/segmentHoverChromium.png
new file mode 100755
index 0000000..0a743d9
--- /dev/null
+++ b/Source/WebKit/chromium/src/js/Images/segmentHoverChromium.png
Binary files differ
diff --git a/Source/WebKit/chromium/src/js/Images/segmentHoverEndChromium.png b/Source/WebKit/chromium/src/js/Images/segmentHoverEndChromium.png
new file mode 100755
index 0000000..cf62072
--- /dev/null
+++ b/Source/WebKit/chromium/src/js/Images/segmentHoverEndChromium.png
Binary files differ
diff --git a/Source/WebKit/chromium/src/js/Images/segmentSelectedChromium.png b/Source/WebKit/chromium/src/js/Images/segmentSelectedChromium.png
new file mode 100755
index 0000000..a1f7251
--- /dev/null
+++ b/Source/WebKit/chromium/src/js/Images/segmentSelectedChromium.png
Binary files differ
diff --git a/Source/WebKit/chromium/src/js/Images/segmentSelectedEndChromium.png b/Source/WebKit/chromium/src/js/Images/segmentSelectedEndChromium.png
new file mode 100755
index 0000000..07641db
--- /dev/null
+++ b/Source/WebKit/chromium/src/js/Images/segmentSelectedEndChromium.png
Binary files differ
diff --git a/Source/WebKit/chromium/src/js/Images/statusbarBackgroundChromium.png b/Source/WebKit/chromium/src/js/Images/statusbarBackgroundChromium.png
new file mode 100755
index 0000000..7a760c1
--- /dev/null
+++ b/Source/WebKit/chromium/src/js/Images/statusbarBackgroundChromium.png
Binary files differ
diff --git a/Source/WebKit/chromium/src/js/Images/statusbarBottomBackgroundChromium.png b/Source/WebKit/chromium/src/js/Images/statusbarBottomBackgroundChromium.png
new file mode 100755
index 0000000..e3bc944
--- /dev/null
+++ b/Source/WebKit/chromium/src/js/Images/statusbarBottomBackgroundChromium.png
Binary files differ
diff --git a/Source/WebKit/chromium/src/js/Images/statusbarButtonsChromium.png b/Source/WebKit/chromium/src/js/Images/statusbarButtonsChromium.png
new file mode 100755
index 0000000..136d5a8
--- /dev/null
+++ b/Source/WebKit/chromium/src/js/Images/statusbarButtonsChromium.png
Binary files differ
diff --git a/Source/WebKit/chromium/src/js/Images/statusbarMenuButtonChromium.png b/Source/WebKit/chromium/src/js/Images/statusbarMenuButtonChromium.png
new file mode 100755
index 0000000..5ff61d9
--- /dev/null
+++ b/Source/WebKit/chromium/src/js/Images/statusbarMenuButtonChromium.png
Binary files differ
diff --git a/Source/WebKit/chromium/src/js/Images/statusbarMenuButtonSelectedChromium.png b/Source/WebKit/chromium/src/js/Images/statusbarMenuButtonSelectedChromium.png
new file mode 100755
index 0000000..3c0aeec
--- /dev/null
+++ b/Source/WebKit/chromium/src/js/Images/statusbarMenuButtonSelectedChromium.png
Binary files differ
diff --git a/Source/WebKit/chromium/src/js/Tests.js b/Source/WebKit/chromium/src/js/Tests.js
new file mode 100644
index 0000000..f2e8dcb
--- /dev/null
+++ b/Source/WebKit/chromium/src/js/Tests.js
@@ -0,0 +1,838 @@
+/*
+ * 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.
+ */
+
+
+/**
+ * @fileoverview This file contains small testing framework along with the
+ * test suite for the frontend. These tests are a part of the continues build
+ * and are executed by the devtools_sanity_unittest.cc as a part of the
+ * Interactive UI Test suite.
+ * FIXME: change field naming style to use trailing underscore.
+ */
+
+if (window.domAutomationController) {
+
+var ___interactiveUiTestsMode = true;
+
+/**
+ * Test suite for interactive UI tests.
+ * @constructor
+ */
+TestSuite = function()
+{
+ this.controlTaken_ = false;
+ this.timerId_ = -1;
+};
+
+
+/**
+ * Reports test failure.
+ * @param {string} message Failure description.
+ */
+TestSuite.prototype.fail = function(message)
+{
+ if (this.controlTaken_)
+ this.reportFailure_(message);
+ else
+ throw message;
+};
+
+
+/**
+ * Equals assertion tests that expected === actual.
+ * @param {Object} expected Expected object.
+ * @param {Object} actual Actual object.
+ * @param {string} opt_message User message to print if the test fails.
+ */
+TestSuite.prototype.assertEquals = function(expected, actual, opt_message)
+{
+ if (expected !== actual) {
+ var message = "Expected: '" + expected + "', but was '" + actual + "'";
+ if (opt_message)
+ message = opt_message + "(" + message + ")";
+ this.fail(message);
+ }
+};
+
+
+/**
+ * True assertion tests that value == true.
+ * @param {Object} value Actual object.
+ * @param {string} opt_message User message to print if the test fails.
+ */
+TestSuite.prototype.assertTrue = function(value, opt_message)
+{
+ this.assertEquals(true, !!value, opt_message);
+};
+
+
+/**
+ * Contains assertion tests that string contains substring.
+ * @param {string} string Outer.
+ * @param {string} substring Inner.
+ */
+TestSuite.prototype.assertContains = function(string, substring)
+{
+ if (string.indexOf(substring) === -1)
+ this.fail("Expected to: '" + string + "' to contain '" + substring + "'");
+};
+
+
+/**
+ * Takes control over execution.
+ */
+TestSuite.prototype.takeControl = function()
+{
+ this.controlTaken_ = true;
+ // Set up guard timer.
+ var self = this;
+ this.timerId_ = setTimeout(function() {
+ self.reportFailure_("Timeout exceeded: 20 sec");
+ }, 20000);
+};
+
+
+/**
+ * Releases control over execution.
+ */
+TestSuite.prototype.releaseControl = function()
+{
+ if (this.timerId_ !== -1) {
+ clearTimeout(this.timerId_);
+ this.timerId_ = -1;
+ }
+ this.reportOk_();
+};
+
+
+/**
+ * Async tests use this one to report that they are completed.
+ */
+TestSuite.prototype.reportOk_ = function()
+{
+ window.domAutomationController.send("[OK]");
+};
+
+
+/**
+ * Async tests use this one to report failures.
+ */
+TestSuite.prototype.reportFailure_ = function(error)
+{
+ if (this.timerId_ !== -1) {
+ clearTimeout(this.timerId_);
+ this.timerId_ = -1;
+ }
+ window.domAutomationController.send("[FAILED] " + error);
+};
+
+
+/**
+ * Runs all global functions starting with "test" as unit tests.
+ */
+TestSuite.prototype.runTest = function(testName)
+{
+ try {
+ this[testName]();
+ if (!this.controlTaken_)
+ this.reportOk_();
+ } catch (e) {
+ this.reportFailure_(e);
+ }
+};
+
+
+/**
+ * @param {string} panelName Name of the panel to show.
+ */
+TestSuite.prototype.showPanel = function(panelName)
+{
+ // Open Scripts panel.
+ var toolbar = document.getElementById("toolbar");
+ var button = toolbar.getElementsByClassName(panelName)[0];
+ button.click();
+ this.assertEquals(WebInspector.panels[panelName], WebInspector.currentPanel);
+};
+
+
+/**
+ * Overrides the method with specified name until it's called first time.
+ * @param {Object} receiver An object whose method to override.
+ * @param {string} methodName Name of the method to override.
+ * @param {Function} override A function that should be called right after the
+ * overriden method returns.
+ * @param {boolean} opt_sticky Whether restore original method after first run
+ * or not.
+ */
+TestSuite.prototype.addSniffer = function(receiver, methodName, override, opt_sticky)
+{
+ var orig = receiver[methodName];
+ if (typeof orig !== "function")
+ this.fail("Cannot find method to override: " + methodName);
+ var test = this;
+ receiver[methodName] = function(var_args) {
+ try {
+ var result = orig.apply(this, arguments);
+ } finally {
+ if (!opt_sticky)
+ receiver[methodName] = orig;
+ }
+ // In case of exception the override won't be called.
+ try {
+ override.apply(this, arguments);
+ } catch (e) {
+ test.fail("Exception in overriden method '" + methodName + "': " + e);
+ }
+ return result;
+ };
+};
+
+
+TestSuite.prototype.testEnableResourcesTab = function()
+{
+ // FIXME once reference is removed downstream.
+}
+
+TestSuite.prototype.testCompletionOnPause = function()
+{
+ // FIXME once reference is removed downstream.
+}
+
+// UI Tests
+
+
+/**
+ * Tests that profiler works.
+ */
+TestSuite.prototype.testProfilerTab = function()
+{
+ this.showPanel("profiles");
+
+ var panel = WebInspector.panels.profiles;
+ var test = this;
+
+ function findDisplayedNode() {
+ var node = panel.visibleView.profileDataGridTree.children[0];
+ if (!node) {
+ // Profile hadn't been queried yet, re-schedule.
+ window.setTimeout(findDisplayedNode, 100);
+ return;
+ }
+
+ // Iterate over displayed functions and search for a function
+ // that is called "fib" or "eternal_fib". If found, this will mean
+ // that we actually have profiled page's code.
+ while (node) {
+ if (node.functionName.indexOf("fib") !== -1)
+ test.releaseControl();
+ node = node.traverseNextNode(true, null, true);
+ }
+
+ test.fail();
+ }
+
+ function findVisibleView() {
+ if (!panel.visibleView) {
+ setTimeout(findVisibleView, 0);
+ return;
+ }
+ setTimeout(findDisplayedNode, 0);
+ }
+
+ findVisibleView();
+ this.takeControl();
+};
+
+
+/**
+ * Tests that heap profiler works.
+ */
+TestSuite.prototype.testHeapProfiler = function()
+{
+ this.showPanel("profiles");
+
+ var panel = WebInspector.panels.profiles;
+ var test = this;
+
+ function findDisplayedNode() {
+ var node = panel.visibleView.dataGrid.children[0];
+ if (!node) {
+ // Profile hadn't been queried yet, re-schedule.
+ window.setTimeout(findDisplayedNode, 100);
+ return;
+ }
+
+ // Iterate over displayed functions and find node called "A"
+ // If found, this will mean that we actually have taken heap snapshot.
+ while (node) {
+ if (node.constructorName.indexOf("A") !== -1) {
+ test.releaseControl();
+ return;
+ }
+ node = node.traverseNextNode(false, null, true);
+ }
+
+ test.fail();
+ }
+
+ function findVisibleView() {
+ if (!panel.visibleView) {
+ setTimeout(findVisibleView, 0);
+ return;
+ }
+ setTimeout(findDisplayedNode, 0);
+ }
+
+ WebInspector.HeapSnapshotProfileType.prototype.buttonClicked();
+ findVisibleView();
+ this.takeControl();
+};
+
+
+/**
+ * Tests that scripts tab can be open and populated with inspected scripts.
+ */
+TestSuite.prototype.testShowScriptsTab = function()
+{
+ this.showPanel("scripts");
+ var test = this;
+ // There should be at least main page script.
+ this._waitUntilScriptsAreParsed(["debugger_test_page.html"],
+ function() {
+ test.releaseControl();
+ });
+ // Wait until all scripts are added to the debugger.
+ this.takeControl();
+};
+
+
+/**
+ * Tests that scripts tab is populated with inspected scripts even if it
+ * hadn't been shown by the moment inspected paged refreshed.
+ * @see http://crbug.com/26312
+ */
+TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh = function()
+{
+ var test = this;
+ this.assertEquals(WebInspector.panels.elements, WebInspector.currentPanel, "Elements panel should be current one.");
+
+ this.addSniffer(WebInspector.panels.scripts, "reset", waitUntilScriptIsParsed);
+
+ // Reload inspected page. It will reset the debugger agent.
+ test.evaluateInConsole_(
+ "window.location.reload(true);",
+ function(resultText) {});
+
+ function waitUntilScriptIsParsed() {
+ test.showPanel("scripts");
+ test._waitUntilScriptsAreParsed(["debugger_test_page.html"],
+ function() {
+ test.releaseControl();
+ });
+ }
+
+ // Wait until all scripts are added to the debugger.
+ this.takeControl();
+};
+
+
+/**
+ * Tests that scripts list contains content scripts.
+ */
+TestSuite.prototype.testContentScriptIsPresent = function()
+{
+ this.showPanel("scripts");
+ var test = this;
+
+ test._waitUntilScriptsAreParsed(
+ ["page_with_content_script.html", "simple_content_script.js"],
+ function() {
+ test.releaseControl();
+ });
+
+ // Wait until all scripts are added to the debugger.
+ this.takeControl();
+};
+
+
+/**
+ * Tests that scripts are not duplicaed on Scripts tab switch.
+ */
+TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch = function()
+{
+ var test = this;
+
+ // There should be two scripts: one for the main page and another
+ // one which is source of console API(see
+ // InjectedScript._ensureCommandLineAPIInstalled).
+ var expectedScriptsCount = 2;
+ var parsedScripts = [];
+
+ this.showPanel("scripts");
+
+
+ function switchToElementsTab() {
+ test.showPanel("elements");
+ setTimeout(switchToScriptsTab, 0);
+ }
+
+ function switchToScriptsTab() {
+ test.showPanel("scripts");
+ setTimeout(checkScriptsPanel, 0);
+ }
+
+ function checkScriptsPanel() {
+ test.assertTrue(!!WebInspector.panels.scripts.visibleView, "No visible script view.");
+ test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html"]), "Some scripts are missing.");
+ checkNoDuplicates();
+ test.releaseControl();
+ }
+
+ function checkNoDuplicates() {
+ var scriptSelect = document.getElementById("scripts-files");
+ var options = scriptSelect.options;
+ for (var i = 0; i < options.length; i++) {
+ var scriptName = options[i].text;
+ for (var j = i + 1; j < options.length; j++)
+ test.assertTrue(scriptName !== options[j].text, "Found script duplicates: " + test.optionsToString_(options));
+ }
+ }
+
+ test._waitUntilScriptsAreParsed(
+ ["debugger_test_page.html"],
+ function() {
+ checkNoDuplicates();
+ setTimeout(switchToElementsTab, 0);
+ });
+
+
+ // Wait until all scripts are added to the debugger.
+ this.takeControl();
+};
+
+
+// Tests that debugger works correctly if pause event occurs when DevTools
+// frontend is being loaded.
+TestSuite.prototype.testPauseWhenLoadingDevTools = function()
+{
+ this.showPanel("scripts");
+ var test = this;
+
+ var expectations = {
+ functionsOnStack: ["callDebugger"],
+ lineNumber: 8,
+ lineText: " debugger;"
+ };
+
+
+ // Script execution can already be paused.
+ if (WebInspector.currentPanel.paused) {
+ var callFrame = WebInspector.currentPanel.sidebarPanes.callstack.selectedCallFrame;
+ this.assertEquals(expectations.functionsOnStack[0], callFrame.functionName);
+ var callbackInvoked = false;
+ this._checkSourceFrameWhenLoaded(expectations, function() {
+ callbackInvoked = true;
+ if (test.controlTaken_)
+ test.releaseControl();
+ });
+ if (!callbackInvoked) {
+ test.takeControl();
+ }
+ return;
+ }
+
+ this._waitForScriptPause(
+ {
+ functionsOnStack: ["callDebugger"],
+ lineNumber: 8,
+ lineText: " debugger;"
+ },
+ function() {
+ test.releaseControl();
+ });
+ this.takeControl();
+};
+
+
+// Tests that pressing "Pause" will pause script execution if the script
+// is already running.
+TestSuite.prototype.testPauseWhenScriptIsRunning = function()
+{
+ this.showPanel("scripts");
+ var test = this;
+
+ test.evaluateInConsole_(
+ 'setTimeout("handleClick()" , 0)',
+ function(resultText) {
+ test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText);
+ testScriptPauseAfterDelay();
+ });
+
+ // Wait for some time to make sure that inspected page is running the
+ // infinite loop.
+ function testScriptPauseAfterDelay() {
+ setTimeout(testScriptPause, 300);
+ }
+
+ function testScriptPause() {
+ // The script should be in infinite loop. Click "Pause" button to
+ // pause it and wait for the result.
+ WebInspector.panels.scripts.pauseButton.click();
+
+ test._waitForScriptPause(
+ {
+ functionsOnStack: ["handleClick", ""],
+ lineNumber: 5,
+ lineText: " while(true) {"
+ },
+ function() {
+ test.releaseControl();
+ });
+ }
+
+ this.takeControl();
+};
+
+
+/**
+ * Serializes options collection to string.
+ * @param {HTMLOptionsCollection} options
+ * @return {string}
+ */
+TestSuite.prototype.optionsToString_ = function(options)
+{
+ var names = [];
+ for (var i = 0; i < options.length; i++)
+ names.push('"' + options[i].text + '"');
+ return names.join(",");
+};
+
+
+/**
+ * Ensures that main HTML resource is selected in Scripts panel and that its
+ * source frame is setup. Invokes the callback when the condition is satisfied.
+ * @param {HTMLOptionsCollection} options
+ * @param {function(WebInspector.SourceView,string)} callback
+ */
+TestSuite.prototype.showMainPageScriptSource_ = function(scriptName, callback)
+{
+ var test = this;
+
+ var scriptSelect = document.getElementById("scripts-files");
+ var options = scriptSelect.options;
+
+ test.assertTrue(options.length, "Scripts list is empty");
+
+ // Select page's script if it's not current option.
+ var scriptResource;
+ if (options[scriptSelect.selectedIndex].text === scriptName)
+ scriptResource = options[scriptSelect.selectedIndex].representedObject;
+ else {
+ var pageScriptIndex = -1;
+ for (var i = 0; i < options.length; i++) {
+ if (options[i].text === scriptName) {
+ pageScriptIndex = i;
+ break;
+ }
+ }
+ test.assertTrue(-1 !== pageScriptIndex, "Script with url " + scriptName + " not found among " + test.optionsToString_(options));
+ scriptResource = options[pageScriptIndex].representedObject;
+
+ // Current panel is "Scripts".
+ WebInspector.currentPanel._showScriptOrResource(scriptResource);
+ test.assertEquals(pageScriptIndex, scriptSelect.selectedIndex, "Unexpected selected option index.");
+ }
+
+ test.assertTrue(scriptResource instanceof WebInspector.Resource,
+ "Unexpected resource class.");
+ test.assertTrue(!!scriptResource.url, "Resource URL is null.");
+ test.assertTrue(scriptResource.url.search(scriptName + "$") !== -1, "Main HTML resource should be selected.");
+
+ var scriptsPanel = WebInspector.panels.scripts;
+
+ var view = scriptsPanel.visibleView;
+ test.assertTrue(view instanceof WebInspector.SourceView);
+
+ if (!view.sourceFrame._loaded) {
+ test.addSniffer(view, "_sourceFrameSetupFinished", function(event) {
+ callback(view, scriptResource.url);
+ });
+ } else
+ callback(view, scriptResource.url);
+};
+
+
+/*
+ * Evaluates the code in the console as if user typed it manually and invokes
+ * the callback when the result message is received and added to the console.
+ * @param {string} code
+ * @param {function(string)} callback
+ */
+TestSuite.prototype.evaluateInConsole_ = function(code, callback)
+{
+ WebInspector.showConsole();
+ WebInspector.console.prompt.text = code;
+ WebInspector.console.promptElement.dispatchEvent( TestSuite.createKeyEvent("Enter"));
+
+ this.addSniffer(WebInspector.ConsoleView.prototype, "addMessage",
+ function(commandResult) {
+ callback(commandResult.toMessageElement().textContent);
+ });
+};
+
+
+/**
+ * Checks current execution line against expectations.
+ * @param {WebInspector.SourceFrame} sourceFrame
+ * @param {number} lineNumber Expected line number
+ * @param {string} lineContent Expected line text
+ */
+TestSuite.prototype._checkExecutionLine = function(sourceFrame, lineNumber, lineContent)
+{
+ this.assertEquals(lineNumber, sourceFrame.executionLine, "Unexpected execution line number.");
+ this.assertEquals(lineContent, sourceFrame._textModel.line(lineNumber - 1), "Unexpected execution line text.");
+}
+
+
+/**
+ * Checks that all expected scripts are present in the scripts list
+ * in the Scripts panel.
+ * @param {Array.<string>} expected Regular expressions describing
+ * expected script names.
+ * @return {boolean} Whether all the scripts are in "scripts-files" select
+ * box
+ */
+TestSuite.prototype._scriptsAreParsed = function(expected)
+{
+ var scriptSelect = document.getElementById("scripts-files");
+ var options = scriptSelect.options;
+
+ // Check that at least all the expected scripts are present.
+ var missing = expected.slice(0);
+ for (var i = 0 ; i < options.length; i++) {
+ for (var j = 0; j < missing.length; j++) {
+ if (options[i].text.search(missing[j]) !== -1) {
+ missing.splice(j, 1);
+ break;
+ }
+ }
+ }
+ return missing.length === 0;
+};
+
+
+/**
+ * Waits for script pause, checks expectations, and invokes the callback.
+ * @param {Object} expectations Dictionary of expectations
+ * @param {function():void} callback
+ */
+TestSuite.prototype._waitForScriptPause = function(expectations, callback)
+{
+ var test = this;
+ // Wait until script is paused.
+ test.addSniffer(
+ WebInspector.debuggerModel,
+ "_pausedScript",
+ function(details) {
+ var callFrames = details.callFrames;
+ var functionsOnStack = [];
+ for (var i = 0; i < callFrames.length; i++)
+ functionsOnStack.push(callFrames[i].functionName);
+
+ test.assertEquals(expectations.functionsOnStack.join(","), functionsOnStack.join(","), "Unexpected stack.");
+
+ // Check that execution line where the script is paused is
+ // expected one.
+ test._checkSourceFrameWhenLoaded(expectations, callback);
+ });
+};
+
+
+/**
+ * Waits for current source frame to load, checks expectations, and invokes
+ * the callback.
+ * @param {Object} expectations Dictionary of expectations
+ * @param {function():void} callback
+ */
+TestSuite.prototype._checkSourceFrameWhenLoaded = function(expectations, callback)
+{
+ var test = this;
+
+ var frame = WebInspector.currentPanel.visibleView.sourceFrame;
+ if (frame._loaded)
+ checkExecLine();
+ else {
+ setTimeout(function() {
+ test._checkSourceFrameWhenLoaded(expectations, callback);
+ }, 100);
+ }
+ function checkExecLine() {
+ test._checkExecutionLine(frame, expectations.lineNumber, expectations.lineText);
+ callback();
+ }
+};
+
+
+/**
+ * Waits until all the scripts are parsed and asynchronously executes the code
+ * in the inspected page.
+ */
+TestSuite.prototype._executeCodeWhenScriptsAreParsed = function(code, expectedScripts)
+{
+ var test = this;
+
+ function executeFunctionInInspectedPage() {
+ // Since breakpoints are ignored in evals' calculate() function is
+ // execute after zero-timeout so that the breakpoint is hit.
+ test.evaluateInConsole_(
+ 'setTimeout("' + code + '" , 0)',
+ function(resultText) {
+ test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText + ". Code: " + code);
+ });
+ }
+
+ test._waitUntilScriptsAreParsed(expectedScripts, executeFunctionInInspectedPage);
+};
+
+
+/**
+ * Waits until all the scripts are parsed and invokes the callback.
+ */
+TestSuite.prototype._waitUntilScriptsAreParsed = function(expectedScripts, callback)
+{
+ var test = this;
+
+ function waitForAllScripts() {
+ if (test._scriptsAreParsed(expectedScripts))
+ callback();
+ else
+ test.addSniffer(WebInspector.debuggerModel, "_parsedScriptSource", waitForAllScripts);
+ }
+
+ waitForAllScripts();
+};
+
+
+/**
+ * Executes the 'code' with InjectedScriptAccess.getProperties overriden
+ * so that all callbacks passed to InjectedScriptAccess.getProperties are
+ * extended with the "hook".
+ * @param {Function} hook The hook function.
+ * @param {Function} code A code snippet to be executed.
+ */
+TestSuite.prototype._hookGetPropertiesCallback = function(hook, code)
+{
+ var accessor = InjectedScriptAccess.prototype;
+ var orig = accessor.getProperties;
+ accessor.getProperties = function(objectProxy, ignoreHasOwnProperty, abbreviate, callback) {
+ orig.call(this, objectProxy, ignoreHasOwnProperty, abbreviate,
+ function() {
+ callback.apply(this, arguments);
+ hook();
+ });
+ };
+ try {
+ code();
+ } finally {
+ accessor.getProperties = orig;
+ }
+};
+
+
+/**
+ * Key event with given key identifier.
+ */
+TestSuite.createKeyEvent = function(keyIdentifier)
+{
+ var evt = document.createEvent("KeyboardEvent");
+ evt.initKeyboardEvent("keydown", true /* can bubble */, true /* can cancel */, null /* view */, keyIdentifier, "");
+ return evt;
+};
+
+
+/**
+ * Test runner for the test suite.
+ */
+var uiTests = {};
+
+
+/**
+ * Run each test from the test suit on a fresh instance of the suite.
+ */
+uiTests.runAllTests = function()
+{
+ // For debugging purposes.
+ for (var name in TestSuite.prototype) {
+ if (name.substring(0, 4) === "test" && typeof TestSuite.prototype[name] === "function")
+ uiTests.runTest(name);
+ }
+};
+
+
+/**
+ * Run specified test on a fresh instance of the test suite.
+ * @param {string} name Name of a test method from TestSuite class.
+ */
+uiTests.runTest = function(name)
+{
+ if (uiTests._populatedInterface)
+ new TestSuite().runTest(name);
+ else
+ uiTests._pendingTestName = name;
+};
+
+(function() {
+
+function runTests()
+{
+ uiTests._populatedInterface = true;
+ var name = uiTests._pendingTestName;
+ delete uiTests._pendingTestName;
+ if (name)
+ new TestSuite().runTest(name);
+}
+
+var oldShowElementsPanel = WebInspector.showElementsPanel;
+WebInspector.showElementsPanel = function()
+{
+ oldShowElementsPanel.call(this);
+ runTests();
+}
+
+var oldShowPanel = WebInspector.showPanel;
+WebInspector.showPanel = function(name)
+{
+ oldShowPanel.call(this, name);
+ runTests();
+}
+
+})();
+
+}
diff --git a/Source/WebKit/chromium/src/js/devTools.css b/Source/WebKit/chromium/src/js/devTools.css
new file mode 100644
index 0000000..64ea9d5
--- /dev/null
+++ b/Source/WebKit/chromium/src/js/devTools.css
@@ -0,0 +1,117 @@
+.data-grid table {
+ line-height: 120%;
+}
+
+body.attached #toolbar {
+ height: 34px;
+ border-top: 1px solid rgb(100, 100, 100);
+ cursor: default; /* overriden */
+ padding-left: 0;
+}
+
+/* Chrome theme overrides */
+
+body.platform-windows #toolbar, body.platform-windows.inactive #toolbar {
+ background-image: none;
+}
+
+body.detached.platform-mac-leopard #toolbar {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(175, 175, 175)), to(rgb(151, 151, 151))) !important;
+}
+
+body.detached.platform-mac-leopard.inactive #toolbar {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(221, 221, 221)), to(rgb(207, 207, 207))) !important;
+}
+
+body.detached.platform-mac-snowleopard #toolbar {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(189, 189, 189)), to(rgb(151, 151, 151))) !important;
+}
+
+body.detached.platform-mac-snowleopard.inactive #toolbar {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(215, 215, 215)), to(rgb(207, 207, 207))) !important;
+}
+
+body.platform-linux #scripts-files {
+ font-size: 11px;
+ font-weight: normal;
+ line-height: 12px;
+}
+
+.console-group-messages .section > .header {
+ padding: 0 8px 0 0;
+ background-image: none;
+ border: none;
+ min-height: 0;
+}
+
+#resources-filter {
+ background: -webkit-gradient(linear, left top, left bottom, from(rgb(233, 233, 233)), to(rgb(233, 233, 233)));
+}
+
+.crumbs .crumb {
+ -webkit-border-image: url(Images/segmentChromium.png) 0 12 0 2;
+ margin-right: -3px;
+ padding-left: 6px;
+}
+
+.crumbs .crumb.selected {
+ -webkit-border-image: url(Images/segmentSelectedChromium.png) 0 12 0 2;
+ color: white;
+ text-shadow: rgba(255, 255, 255, 0.5) 0 0px 0;
+}
+
+.crumbs .crumb.selected:hover {
+ -webkit-border-image: url(Images/segmentSelectedChromium.png) 0 12 0 2;
+}
+
+.crumbs .crumb.selected.end, .crumbs .crumb.selected.end:hover {
+ -webkit-border-image: url(Images/segmentSelectedEndChromium.png) 0 2 0 2;
+}
+
+.crumbs .crumb:hover {
+ -webkit-border-image: url(Images/segmentHoverChromium.png) 0 12 0 2;
+}
+
+.crumbs .crumb.dimmed:hover {
+ -webkit-border-image: url(Images/segmentHoverChromium.png) 0 12 0 2;
+}
+
+.crumbs .crumb.end:hover {
+ -webkit-border-image: url(Images/segmentHoverEndChromium.png) 0 2 0 2;
+}
+
+body.drawer-visible #main-status-bar {
+ background-image: url(Images/statusbarResizerVertical.png), url(Images/statusbarBackgroundChromium.png);
+}
+
+.status-bar {
+ background-image: url(Images/statusbarBackgroundChromium.png);
+}
+
+button.status-bar-item {
+ background-image: url(Images/statusbarButtonsChromium.png);
+}
+
+select.status-bar-item:active {
+ -webkit-border-image: url(Images/statusbarMenuButtonSelectedChromium.png) 0 17 0 2;
+}
+
+#drawer {
+ background-image: url(Images/statusbarBottomBackgroundChromium.png);
+}
+
+select.status-bar-item {
+ -webkit-border-image: url(Images/statusbarMenuButtonChromium.png) 0 17 0 2;
+}
+
+.scope-bar li.selected {
+ -webkit-box-shadow: 0px 0px 0px rgba(0, 0, 0, 0.0);
+}
+
+.scope-bar li:active {
+ -webkit-box-shadow: 0px 0px 0px rgba(0, 0, 0, 0.0);
+}
+
+.timeline-category-statusbar-item input {
+ vertical-align: middle;
+}