summaryrefslogtreecommitdiffstats
path: root/WebKit
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit')
-rw-r--r--WebKit/ChangeLog19
-rw-r--r--WebKit/WebKit.xcodeproj/project.pbxproj16
-rw-r--r--WebKit/chromium/ChangeLog1271
-rw-r--r--WebKit/chromium/DEPS23
-rw-r--r--WebKit/chromium/WebKit.gyp13
-rw-r--r--WebKit/chromium/WebKit.gypi67
-rw-r--r--WebKit/chromium/features.gypi3
-rw-r--r--WebKit/chromium/public/WebContextMenuData.h3
-rw-r--r--WebKit/chromium/public/WebDatabase.h2
-rw-r--r--WebKit/chromium/public/WebDragData.h2
-rw-r--r--WebKit/chromium/public/WebFileInfo.h46
-rw-r--r--WebKit/chromium/public/WebHTTPBody.h8
-rw-r--r--WebKit/chromium/public/WebInputElement.h4
-rw-r--r--WebKit/chromium/public/WebKitClient.h1
-rw-r--r--WebKit/chromium/public/WebStorageArea.h26
-rw-r--r--WebKit/chromium/public/WebView.h24
-rw-r--r--WebKit/chromium/public/WebViewClient.h3
-rw-r--r--WebKit/chromium/src/AutoFillPopupMenuClient.cpp95
-rw-r--r--WebKit/chromium/src/AutoFillPopupMenuClient.h80
-rw-r--r--WebKit/chromium/src/AutocompletePopupMenuClient.cpp134
-rw-r--r--WebKit/chromium/src/AutocompletePopupMenuClient.h59
-rw-r--r--WebKit/chromium/src/BackForwardListClientImpl.cpp2
-rw-r--r--WebKit/chromium/src/ChromeClientImpl.cpp8
-rw-r--r--WebKit/chromium/src/ChromeClientImpl.h2
-rw-r--r--WebKit/chromium/src/DebuggerAgent.h5
-rw-r--r--WebKit/chromium/src/DebuggerAgentImpl.cpp45
-rw-r--r--WebKit/chromium/src/DebuggerAgentImpl.h5
-rw-r--r--WebKit/chromium/src/EditorClientImpl.cpp6
-rw-r--r--WebKit/chromium/src/GraphicsContext3D.cpp30
-rw-r--r--WebKit/chromium/src/SuggestionsPopupMenuClient.cpp186
-rw-r--r--WebKit/chromium/src/SuggestionsPopupMenuClient.h109
-rw-r--r--WebKit/chromium/src/ToolsAgent.h3
-rw-r--r--WebKit/chromium/src/WebDatabase.cpp18
-rw-r--r--WebKit/chromium/src/WebDevToolsAgentImpl.cpp9
-rw-r--r--WebKit/chromium/src/WebDevToolsAgentImpl.h1
-rw-r--r--WebKit/chromium/src/WebDevToolsFrontendImpl.cpp3
-rw-r--r--WebKit/chromium/src/WebDragData.cpp12
-rw-r--r--WebKit/chromium/src/WebHTTPBody.cpp12
-rw-r--r--WebKit/chromium/src/WebInputElement.cpp7
-rw-r--r--WebKit/chromium/src/WebRuntimeFeatures.cpp8
-rw-r--r--WebKit/chromium/src/WebStorageAreaImpl.cpp6
-rw-r--r--WebKit/chromium/src/WebStorageAreaImpl.h2
-rw-r--r--WebKit/chromium/src/WebViewImpl.cpp222
-rw-r--r--WebKit/chromium/src/WebViewImpl.h55
-rw-r--r--WebKit/chromium/src/WebWorkerBase.cpp2
-rw-r--r--WebKit/chromium/src/js/DebuggerAgent.js1528
-rw-r--r--WebKit/chromium/src/js/DevTools.js504
-rw-r--r--WebKit/chromium/src/js/DevToolsHostStub.js309
-rw-r--r--WebKit/chromium/src/js/HeapProfilerPanel.js966
-rwxr-xr-xWebKit/chromium/src/js/Images/segmentChromium.pngbin0 -> 4253 bytes
-rwxr-xr-xWebKit/chromium/src/js/Images/segmentHoverChromium.pngbin0 -> 4160 bytes
-rwxr-xr-xWebKit/chromium/src/js/Images/segmentHoverEndChromium.pngbin0 -> 4143 bytes
-rwxr-xr-xWebKit/chromium/src/js/Images/segmentSelectedChromium.pngbin0 -> 4113 bytes
-rwxr-xr-xWebKit/chromium/src/js/Images/segmentSelectedEndChromium.pngbin0 -> 4104 bytes
-rwxr-xr-xWebKit/chromium/src/js/Images/statusbarBackgroundChromium.pngbin0 -> 4070 bytes
-rwxr-xr-xWebKit/chromium/src/js/Images/statusbarBottomBackgroundChromium.pngbin0 -> 4070 bytes
-rwxr-xr-xWebKit/chromium/src/js/Images/statusbarButtonsChromium.pngbin0 -> 4258 bytes
-rwxr-xr-xWebKit/chromium/src/js/Images/statusbarMenuButtonChromium.pngbin0 -> 4391 bytes
-rwxr-xr-xWebKit/chromium/src/js/Images/statusbarMenuButtonSelectedChromium.pngbin0 -> 4372 bytes
-rw-r--r--WebKit/chromium/src/js/InjectDispatch.js106
-rw-r--r--WebKit/chromium/src/js/InspectorControllerImpl.js279
-rw-r--r--WebKit/chromium/src/js/ProfilerAgent.js227
-rw-r--r--WebKit/chromium/src/js/ProfilerProcessor.js543
-rw-r--r--WebKit/chromium/src/js/Tests.js1862
-rwxr-xr-xWebKit/chromium/src/js/devTools.css223
-rw-r--r--WebKit/chromium/tests/TransparencyWinTest.cpp693
-rw-r--r--WebKit/chromium/tests/UniscribeHelperTest.cpp165
-rw-r--r--WebKit/gtk/ChangeLog94
-rw-r--r--WebKit/gtk/NEWS14
-rw-r--r--WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp53
-rw-r--r--WebKit/gtk/tests/testwebview.c104
-rw-r--r--WebKit/gtk/webkit/webkitprivate.h3
-rw-r--r--WebKit/gtk/webkit/webkitwebframe.cpp26
-rw-r--r--WebKit/gtk/webkit/webkitwebview.cpp63
-rw-r--r--WebKit/mac/ChangeLog186
-rw-r--r--WebKit/mac/Configurations/FeatureDefines.xcconfig3
-rw-r--r--WebKit/mac/Configurations/Version.xcconfig4
-rw-r--r--WebKit/mac/ForwardingHeaders/wtf/ValueCheck.h1
-rw-r--r--WebKit/mac/MigrateHeaders.make2
-rw-r--r--WebKit/mac/Misc/WebCoreStatistics.h2
-rw-r--r--WebKit/mac/Misc/WebCoreStatistics.mm20
-rw-r--r--WebKit/mac/Misc/WebLocalizableStrings.mm (renamed from WebKit/mac/Misc/WebLocalizableStrings.m)7
-rw-r--r--WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm105
-rw-r--r--WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h5
-rw-r--r--WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm25
-rw-r--r--WebKit/mac/Plugins/Hosted/ProxyInstance.mm5
-rw-r--r--WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm16
-rw-r--r--WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs15
-rw-r--r--WebKit/mac/Plugins/WebBaseNetscapePluginView.h1
-rw-r--r--WebKit/mac/Plugins/WebBaseNetscapePluginView.mm16
-rw-r--r--WebKit/mac/Plugins/WebNetscapePluginView.mm27
-rw-r--r--WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm8
-rw-r--r--WebKit/mac/WebView/WebFrameView.mm6
-rw-r--r--WebKit/mac/WebView/WebPDFDocumentExtras.h8
-rw-r--r--WebKit/mac/WebView/WebPDFDocumentExtras.mm14
-rw-r--r--WebKit/mac/WebView/WebPDFRepresentation.mm12
-rw-r--r--WebKit/mac/WebView/WebPreferenceKeysPrivate.h1
-rw-r--r--WebKit/mac/WebView/WebPreferences.mm11
-rw-r--r--WebKit/mac/WebView/WebPreferencesPrivate.h3
-rw-r--r--WebKit/mac/WebView/WebView.mm1
-rw-r--r--WebKit/qt/Api/DerivedSources.pro96
-rw-r--r--WebKit/qt/Api/qgraphicswebview.cpp11
-rw-r--r--WebKit/qt/Api/qwebelement.cpp1
-rw-r--r--WebKit/qt/Api/qwebframe.cpp13
-rw-r--r--WebKit/qt/Api/qwebpage.cpp12
-rw-r--r--WebKit/qt/Api/qwebpage_p.h3
-rw-r--r--WebKit/qt/Api/qwebview.cpp141
-rw-r--r--WebKit/qt/ChangeLog219
-rw-r--r--WebKit/qt/WebCoreSupport/ChromeClientQt.cpp13
-rw-r--r--WebKit/qt/WebCoreSupport/ChromeClientQt.h2
-rw-r--r--WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp6
-rw-r--r--WebKit/qt/tests/qwebelement/tst_qwebelement.cpp2
-rw-r--r--WebKit/qt/tests/qwebpage/tst_qwebpage.cpp22
-rw-r--r--WebKit/qt/tests/tests.pri3
-rw-r--r--WebKit/win/AccessibleBase.cpp22
-rw-r--r--WebKit/win/ChangeLog110
-rw-r--r--WebKit/win/Interfaces/IWebPreferencesPrivate.idl3
-rw-r--r--WebKit/win/Interfaces/WebKit.idl1
-rw-r--r--WebKit/win/WebFrame.cpp41
-rw-r--r--WebKit/win/WebPreferenceKeysPrivate.h2
-rw-r--r--WebKit/win/WebPreferences.cpp16
-rw-r--r--WebKit/win/WebPreferences.h6
-rw-r--r--WebKit/win/WebView.cpp9
-rw-r--r--WebKit/wx/ChangeLog17
-rw-r--r--WebKit/wx/WebView.cpp12
125 files changed, 11097 insertions, 609 deletions
diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index 1b7118f..134a252 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,22 @@
+2010-02-04 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Timothy Hatcher.
+
+ Build fix. Remove a symbol corresponding to an inline function from the linker export
+ file to prevent a weak external failure.
+
+ * WebKit.xcodeproj/project.pbxproj: Accommodate rename of script.
+
+2010-02-04 John Sullivan <sullivan@apple.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=34611
+ WebLocalizedString() could use an assertion that it is being called on the main thread
+
+ Reviewed by Tim Hatcher.
+
+ * WebKit.xcodeproj/project.pbxproj:
+ Updated for renamed file (WebLocalizableStrings.m -> WebLocalizableStrings.mm)
+
2010-01-29 Mark Rowe <mrowe@apple.com>
Sort Xcode projects.
diff --git a/WebKit/WebKit.xcodeproj/project.pbxproj b/WebKit/WebKit.xcodeproj/project.pbxproj
index f6f4a9e..dda5966 100644
--- a/WebKit/WebKit.xcodeproj/project.pbxproj
+++ b/WebKit/WebKit.xcodeproj/project.pbxproj
@@ -295,7 +295,6 @@
939811070824BF01008DF038 /* WebView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51A8B57A042834F700CA2D3A /* WebView.mm */; };
939811080824BF01008DF038 /* WebPolicyDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51443F9B0429392B00CA2D3A /* WebPolicyDelegate.mm */; };
9398110A0824BF01008DF038 /* WebDefaultUIDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 515E27D00458CA4B00CA2D3A /* WebDefaultUIDelegate.m */; };
- 9398110D0824BF01008DF038 /* WebLocalizableStrings.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE18F9A0472B73200CA289C /* WebLocalizableStrings.m */; };
9398110E0824BF01008DF038 /* WebKitSystemBits.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE52D4B0473032500CA289C /* WebKitSystemBits.m */; };
939811120824BF01008DF038 /* WebNSURLExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = BE6DC39A04C62C4E004D0EF6 /* WebNSURLExtras.mm */; };
939811130824BF01008DF038 /* WebHistory.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65DA2608052CC18700A97B31 /* WebHistory.mm */; };
@@ -349,6 +348,7 @@
DD89682009AA87240097E7F0 /* WebElementDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = DD89681E09AA87240097E7F0 /* WebElementDictionary.h */; };
DD89682109AA87240097E7F0 /* WebElementDictionary.mm in Sources */ = {isa = PBXBuildFile; fileRef = DD89681F09AA87240097E7F0 /* WebElementDictionary.mm */; };
E15663190FB61C1F00C199CA /* WebDownload.mm in Sources */ = {isa = PBXBuildFile; fileRef = E15663180FB61C1F00C199CA /* WebDownload.mm */; };
+ ED5B9524111B725A00472298 /* WebLocalizableStrings.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED5B9523111B725A00472298 /* WebLocalizableStrings.mm */; };
ED6BE2E7088C32B50044DEDC /* WebNSAttributedStringExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = ED6BE2E5088C32B50044DEDC /* WebNSAttributedStringExtras.h */; };
ED6BE2E8088C32B50044DEDC /* WebNSAttributedStringExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED6BE2E6088C32B50044DEDC /* WebNSAttributedStringExtras.mm */; };
ED7F6D8B0980683500C235ED /* WebNSDataExtrasPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = ED7F6D8A0980683500C235ED /* WebNSDataExtrasPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -633,7 +633,6 @@
BECD14290565830A005BB09C /* WebNSDataExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebNSDataExtras.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
BECD142A0565830A005BB09C /* WebNSDataExtras.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebNSDataExtras.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
BEE18F990472B73200CA289C /* WebLocalizableStrings.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebLocalizableStrings.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
- BEE18F9A0472B73200CA289C /* WebLocalizableStrings.m */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebLocalizableStrings.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
BEE52D4A0473032500CA289C /* WebKitSystemBits.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebKitSystemBits.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
BEE52D4B0473032500CA289C /* WebKitSystemBits.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebKitSystemBits.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
C0167BF60D7F5DD00028696E /* WebScriptDebugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebScriptDebugger.h; sourceTree = "<group>"; };
@@ -650,6 +649,7 @@
ED2B2474033A2DA800C1A526 /* WebNSPasteboardExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebNSPasteboardExtras.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
ED2B2475033A2DA800C1A526 /* WebNSPasteboardExtras.mm */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebNSPasteboardExtras.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
ED3B48DE0CC51F7E00DFF1EB /* StringsNotToBeLocalized.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = StringsNotToBeLocalized.txt; sourceTree = SOURCE_ROOT; };
+ ED5B9523111B725A00472298 /* WebLocalizableStrings.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebLocalizableStrings.mm; sourceTree = "<group>"; };
ED6BE2E5088C32B50044DEDC /* WebNSAttributedStringExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebNSAttributedStringExtras.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
ED6BE2E6088C32B50044DEDC /* WebNSAttributedStringExtras.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebNSAttributedStringExtras.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
ED7F6D8A0980683500C235ED /* WebNSDataExtrasPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebNSDataExtrasPrivate.h; sourceTree = "<group>"; };
@@ -917,7 +917,7 @@
1C0D40850AC1C8F40009C113 /* WebKitVersionChecks.h */,
1C0D40860AC1C8F40009C113 /* WebKitVersionChecks.m */,
BEE18F990472B73200CA289C /* WebLocalizableStrings.h */,
- BEE18F9A0472B73200CA289C /* WebLocalizableStrings.m */,
+ ED5B9523111B725A00472298 /* WebLocalizableStrings.mm */,
EDE9837E0BCDF5FE00FDAE28 /* WebNSArrayExtras.h */,
EDE9837F0BCDF5FE00FDAE28 /* WebNSArrayExtras.m */,
ED6BE2E5088C32B50044DEDC /* WebNSAttributedStringExtras.h */,
@@ -1566,7 +1566,7 @@
939811270824BF01008DF038 /* Frameworks */,
939D054F09DA02D500984996 /* Check For Global Initializers */,
9337D6540EBFE54D00DA3CB5 /* Check For Exit Time Destructors */,
- 5D0D54210E98631D0029E223 /* Check For Weak VTables */,
+ 5D0D54210E98631D0029E223 /* Check For Weak VTables and Externals */,
5DE6D18C0FCF231B002DE28C /* Symlink WebKitPluginHost in to place */,
);
buildRules = (
@@ -1654,7 +1654,7 @@
shellPath = /bin/sh;
shellScript = "mkdir -p \"${TARGET_BUILD_DIR}/${PRIVATE_HEADERS_FOLDER_PATH}\"\nmkdir -p \"${TARGET_BUILD_DIR}/${PUBLIC_HEADERS_FOLDER_PATH}\"\nmkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebKit\"\n\nif [ \"${ACTION}\" = \"build\" -o \"${ACTION}\" = \"install\" -o \"${ACTION}\" = \"installhdrs\" ]; then\n make -C mac -f \"MigrateHeaders.make\" -j `/usr/sbin/sysctl -n hw.availcpu`\nfi\n";
};
- 5D0D54210E98631D0029E223 /* Check For Weak VTables */ = {
+ 5D0D54210E98631D0029E223 /* Check For Weak VTables and Externals */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -1662,12 +1662,12 @@
inputPaths = (
"$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)",
);
- name = "Check For Weak VTables";
+ name = "Check For Weak VTables and Externals";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if [ \"${ACTION}\" = \"installhdrs\" ]; then\n exit 0;\nfi\n\nif [ -f ../WebKitTools/Scripts/check-for-weak-vtables ]; then\n ../WebKitTools/Scripts/check-for-weak-vtables || exit $?\nfi";
+ shellScript = "if [ \"${ACTION}\" = \"installhdrs\" ]; then\n exit 0;\nfi\n\nif [ -f ../WebKitTools/Scripts/check-for-weak-vtables-and-externals ]; then\n ../WebKitTools/Scripts/check-for-weak-vtables-and-externals || exit $?\nfi";
};
5D2F7DB70C687A5A00B5B72B /* Update Info.plist with version information */ = {
isa = PBXShellScriptBuildPhase;
@@ -1824,7 +1824,6 @@
939810C50824BF01008DF038 /* WebKitStatistics.m in Sources */,
9398110E0824BF01008DF038 /* WebKitSystemBits.m in Sources */,
1C0D40880AC1C8F40009C113 /* WebKitVersionChecks.m in Sources */,
- 9398110D0824BF01008DF038 /* WebLocalizableStrings.m in Sources */,
5185F62810712B97007AA393 /* WebNavigationData.mm in Sources */,
0AB752380FA2E4DB00D7CBB1 /* WebNetscapeContainerCheckContextInfo.mm in Sources */,
0AEBFF640F9FA8BE000D486B /* WebNetscapeContainerCheckPrivate.mm in Sources */,
@@ -1889,6 +1888,7 @@
939810E80824BF01008DF038 /* WebViewFactory.mm in Sources */,
0FD3B0F91076C3F700039B96 /* WebWindowAnimation.m in Sources */,
41F4485010338E8C0030E55E /* WebWorkersPrivate.mm in Sources */,
+ ED5B9524111B725A00472298 /* WebLocalizableStrings.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 58c37a8..9cd3644 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,1274 @@
+2010-02-12 Jeremy Orlow <jorlow@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ [Chromium] Add a blockedByPolicy output to WebStorageArea::setItem.
+ https://bugs.webkit.org/show_bug.cgi?id=34897
+
+ * public/WebStorageArea.h:
+ (WebKit::WebStorageArea::setItem):
+ * src/WebStorageAreaImpl.cpp:
+ (WebKit::WebStorageAreaImpl::setItem):
+ * src/WebStorageAreaImpl.h:
+
+2010-02-11 Jeremy Orlow <jorlow@chromium.org>
+
+ Reviewed by David Levin.
+
+ [Chromium] Add ENABLE_RUBY to the feature defines gypi
+ https://bugs.webkit.org/show_bug.cgi?id=34841
+
+ * features.gypi:
+
+2010-02-12 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Chromium: Web Inspector on an element in a page where JS is blocked crashes the renderer
+
+ https://bugs.webkit.org/show_bug.cgi?id=34890
+
+ * src/DebuggerAgentImpl.cpp:
+ (WebKit::DebuggerAgentImpl::createUtilityContext):
+
+2010-02-11 Mikhail Naganov <mnaganov@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ [Chromium] Ignore subsequent requests of the same profiler log
+ chunks. This eliminates emission of several instances for the same
+ heap snapshot.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34833
+
+ * src/js/ProfilerAgent.js:
+ (devtools.ProfilerAgent):
+ (devtools.ProfilerAgent.prototype.initializeProfiling):
+ (devtools.ProfilerAgent.prototype._getNextLogLines):
+ (devtools.ProfilerAgent.prototype.startProfiling):
+ (devtools.ProfilerAgent.prototype._didGetActiveProfilerModules):
+ (devtools.ProfilerAgent.prototype._didGetLogLines):
+
+2010-02-10 James Hawkins <jhawkins@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ [Chromium] Remove code from SuggestionsPopup that was removed in a
+ previous revision of AutocompletePopup and accidentally added back in
+ the refactoring.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34818
+
+ * src/AutoFillPopupMenuClient.cpp:
+ * src/AutoFillPopupMenuClient.h: Added property svn:eol-style.
+ * src/SuggestionsPopupMenuClient.cpp:
+ (WebKit::SuggestionsPopupMenuClient::popupDidHide):
+ (WebKit::SuggestionsPopupMenuClient::setTextFromItem):
+ (WebKit::SuggestionsPopupMenuClient::initialize):
+ * src/SuggestionsPopupMenuClient.h:
+
+2010-02-10 Nate Chapin <japhet@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Update call to V8DOMWrapper::lookupDOMWrapper() to match new parameters.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34768
+
+ * src/DebuggerAgentImpl.cpp:
+ (WebKit::DebuggerAgentImpl::createUtilityContext):
+
+2010-02-10 Kenneth Russell <kbr@google.com>
+
+ Reviewed by Oliver Hunt.
+
+ Remove automatic viewport resizing
+ https://bugs.webkit.org/show_bug.cgi?id=34766
+
+ Removed automatic viewport resizing per conclusions on the WebGL
+ mailing list. Added test verifying new behavior and updated a
+ couple of previous tests failing after this change.
+
+ * src/GraphicsContext3D.cpp:
+ (WebCore::GraphicsContext3DInternal::reshape):
+
+2010-02-10 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Chromium Win build fix. Add third_party/nss to the dependencies list on Windows.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34789
+
+ * DEPS:
+
+2010-02-10 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Rolling Chromium dependencies to match Chromium revision 38580.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34789
+
+ * DEPS:
+
+2010-02-10 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Use v8::Debug::ProcessDebugMessages instead of executing an empty function
+
+ https://bugs.webkit.org/show_bug.cgi?id=34704
+
+ * src/DebuggerAgent.h:
+ * src/DebuggerAgentImpl.cpp:
+ (WebKit::DebuggerAgentImpl::processDebugCommands):
+ * src/DebuggerAgentImpl.h:
+ * src/ToolsAgent.h:
+ * src/WebDevToolsAgentImpl.cpp:
+ * src/WebDevToolsAgentImpl.h:
+ * src/js/DebuggerAgent.js:
+ (devtools.DebuggerAgent.prototype.addBreakpoint):
+ * src/js/DevToolsHostStub.js:
+ (.RemoteDebuggerAgentStub.prototype.processDebugCommands):
+ * src/js/InjectDispatch.js:
+ (dispatch):
+ * src/js/ProfilerAgent.js:
+ (devtools.ProfilerAgent.prototype.startProfiling):
+ (devtools.ProfilerAgent.prototype.stopProfiling):
+ * src/js/Tests.js:
+
+2010-02-10 Tony Chang <tony@chromium.org>
+
+ Unreviewed, build fix for Chromium Mac take 2.
+
+ * src/AutoFillPopupMenuClient.cpp:
+ (WebKit::AutoFillPopupMenuClient::removeSuggestionAtIndex):
+
+2010-02-10 Tony Chang <tony@chromium.org>
+
+ Unreviewed, build fix for Chromium Mac.
+
+ * src/AutoFillPopupMenuClient.cpp:
+ (WebKit::AutoFillPopupMenuClient::removeSuggestionAtIndex):
+
+2010-02-09 James Hawkins <jhawkins@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ [Chromium] Refactor AutocompletePopupMenuClient into a base class,
+ SuggestionsPopupMenuClient, and two derived classes,
+ AutocompletePopupMenuClient and AutoFillPopupMenuClient. Currently
+ the behavior of suggestions popups has not changed.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34721
+
+ * WebKit.gyp:
+ * public/WebView.h:
+ * src/AutoFillPopupMenuClient.cpp: Added.
+ * src/AutoFillPopupMenuClient.h: Added.
+ * src/AutocompletePopupMenuClient.cpp:
+ (WebKit::AutocompletePopupMenuClient::getSuggestionsCount):
+ (WebKit::AutocompletePopupMenuClient::getSuggestion):
+ (WebKit::AutocompletePopupMenuClient::removeSuggestionAtIndex):
+ (WebKit::AutocompletePopupMenuClient::initialize):
+ (WebKit::AutocompletePopupMenuClient::setSuggestions):
+ * src/AutocompletePopupMenuClient.h:
+ * src/SuggestionsPopupMenuClient.cpp: Added.
+ * src/SuggestionsPopupMenuClient.h: Added.
+ * src/WebViewImpl.cpp:
+ (WebKit::WebViewImpl::WebViewImpl):
+ (WebKit::WebViewImpl::keyEvent):
+ (WebKit::WebViewImpl::autocompleteHandleKeyEvent):
+ (WebKit::WebViewImpl::applyAutofillSuggestions):
+ (WebKit::WebViewImpl::applyAutoFillSuggestions):
+ (WebKit::WebViewImpl::applyAutocompleteSuggestions):
+ * src/WebViewImpl.h:
+
+2010-02-09 Chris Guillory <ctguil@google.com>
+
+ Reviewed by Darin Fisher.
+
+ [Chromium] Add function for accessibility object state change notifications.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34464
+
+ * gyp_webkit:
+ * public/WebViewClient.h:
+ (WebKit::WebViewClient::didChangeAccessibilityObjectState):
+ * src/ChromeClientImpl.cpp:
+ (WebKit::ChromeClientImpl::didChangeAccessibilityObjectState):
+ * src/ChromeClientImpl.h:
+
+2010-02-09 Mikhail Naganov <mnaganov@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Continuing debugger and profiler unforking: narrow scope of JSC-specific ifdefs.
+ Also, enable JAVASCRIPT_DEBUGGER explicitly in features, it appears to be required
+ for really enabling it in V8 bindings generation.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34706
+
+ * features.gypi:
+
+2010-02-09 Jian Li <jianli@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ [chromium] Add the chromium interface to support Blob.slice.
+ https://bugs.webkit.org/show_bug.cgi?id=34652
+
+ * WebKit.gyp:
+ * public/WebFileInfo.h: Added.
+ * public/WebHTTPBody.h:
+ * src/WebHTTPBody.cpp:
+ (WebKit::WebHTTPBody::elementAt):
+ (WebKit::WebHTTPBody::appendFile):
+
+2010-02-09 Yury Semikhatsky <yurys@chromium.org>
+
+ Unreviewed. Follow-up fix.
+
+ Add missing devTools.css file.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34756
+
+ * src/js/devTools.css: Added.
+
+2010-02-09 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Upstream DevTools Images and .css files.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34756
+
+ * WebKit.gypi:
+ * src/js/DevTools.css: Added.
+ * src/js/Images/segmentChromium.png: Added.
+ * src/js/Images/segmentHoverChromium.png: Added.
+ * src/js/Images/segmentHoverEndChromium.png: Added.
+ * src/js/Images/segmentSelectedChromium.png: Added.
+ * src/js/Images/segmentSelectedEndChromium.png: Added.
+ * src/js/Images/statusbarBackgroundChromium.png: Added.
+ * src/js/Images/statusbarBottomBackgroundChromium.png: Added.
+ * src/js/Images/statusbarButtonsChromium.png: Added.
+ * src/js/Images/statusbarMenuButtonChromium.png: Added.
+ * src/js/Images/statusbarMenuButtonSelectedChromium.png: Added.
+
+2010-02-09 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Upstream JavaScript part of DevTools WebKit API implementation(now
+ with the added files).
+
+ https://bugs.webkit.org/show_bug.cgi?id=34744
+
+ * WebKit.gypi: Added.
+ * src/js/DebuggerAgent.js: Added.
+ (devtools.DebuggerAgent):
+ (devtools.DebuggerAgent.prototype.reset):
+ (devtools.DebuggerAgent.prototype.initUI):
+ (devtools.DebuggerAgent.prototype.resolveScriptSource.this.requestSeqToCallback_.cmd.getSequenceNumber):
+ (devtools.DebuggerAgent.prototype.resolveScriptSource):
+ (devtools.DebuggerAgent.prototype.pauseExecution):
+ (devtools.DebuggerAgent.prototype.addBreakpoint):
+ (devtools.DebuggerAgent.prototype.removeBreakpoint):
+ (devtools.DebuggerAgent.prototype.updateBreakpoint):
+ (devtools.DebuggerAgent.prototype.stepIntoStatement):
+ (devtools.DebuggerAgent.prototype.stepOutOfFunction):
+ (devtools.DebuggerAgent.prototype.stepOverStatement):
+ (devtools.DebuggerAgent.prototype.resumeExecution):
+ (devtools.DebuggerAgent.prototype.createExceptionMessage_):
+ (devtools.DebuggerAgent.prototype.showPendingExceptionMessage_):
+ (devtools.DebuggerAgent.prototype.clearExceptionMessage_):
+ (devtools.DebuggerAgent.prototype.pauseOnExceptions):
+ (devtools.DebuggerAgent.prototype.setPauseOnExceptions):
+ (devtools.DebuggerAgent.prototype.requestEvaluate):
+ (devtools.DebuggerAgent.prototype.resolveChildren):
+ (devtools.DebuggerAgent.prototype.resolveScope.this.requestSeqToCallback_.cmd.getSequenceNumber):
+ (devtools.DebuggerAgent.prototype.resolveScope):
+ (devtools.DebuggerAgent.prototype.resolveFrameVariables_.scopeResponseHandler):
+ (devtools.DebuggerAgent.prototype.resolveFrameVariables_):
+ (devtools.DebuggerAgent.prototype.resolveCompletionsOnFrame):
+ (devtools.DebuggerAgent.prototype.getScriptContextType):
+ (devtools.DebuggerAgent.prototype.requestClearBreakpoint_):
+ (devtools.DebuggerAgent.prototype.requestChangeBreakpoint_):
+ (devtools.DebuggerAgent.prototype.requestBacktrace_):
+ (devtools.DebuggerAgent.sendCommand_):
+ (devtools.DebuggerAgent.prototype.stepCommand_):
+ (devtools.DebuggerAgent.prototype.requestLookup_):
+ (devtools.DebuggerAgent.prototype.setContextId_.this.requestSeqToCallback_.cmd.getSequenceNumber):
+ (devtools.DebuggerAgent.prototype.setContextId_):
+ (devtools.DebuggerAgent.prototype.handleDebuggerOutput_):
+ (devtools.DebuggerAgent.prototype.handleBreakEvent_):
+ (devtools.DebuggerAgent.prototype.handleExceptionEvent_):
+ (devtools.DebuggerAgent.prototype.handleScriptsResponse_):
+ (devtools.DebuggerAgent.prototype.isScriptFromInspectedContext_):
+ (devtools.DebuggerAgent.prototype.handleSetBreakpointResponse_):
+ (devtools.DebuggerAgent.prototype.handleAfterCompileEvent_):
+ (devtools.DebuggerAgent.prototype.addScriptInfo_):
+ (devtools.DebuggerAgent.prototype.handleClearBreakpointResponse_):
+ (devtools.DebuggerAgent.prototype.handleBacktraceResponse_):
+ (devtools.DebuggerAgent.prototype.doHandleBacktraceResponse_):
+ (devtools.DebuggerAgent.prototype.evaluateInCallFrame):
+ (devtools.DebuggerAgent.prototype.invokeCallbackForResponse_):
+ (devtools.DebuggerAgent.prototype.formatCallFrame_):
+ (devtools.DebuggerAgent.formatObjectProperties_):
+ (devtools.DebuggerAgent.propertiesToProxies_):
+ (devtools.DebuggerAgent.formatObjectProxy_):
+ (devtools.DebuggerAgent.webkitToV8LineNumber_):
+ (devtools.DebuggerAgent.v8ToWwebkitLineNumber_):
+ (devtools.ScriptInfo):
+ (devtools.ScriptInfo.prototype.getLineOffset):
+ (devtools.ScriptInfo.prototype.getContextType):
+ (devtools.ScriptInfo.prototype.getUrl):
+ (devtools.ScriptInfo.prototype.isUnresolved):
+ (devtools.ScriptInfo.prototype.getBreakpointInfo):
+ (devtools.ScriptInfo.prototype.addBreakpointInfo):
+ (devtools.ScriptInfo.prototype.removeBreakpointInfo):
+ (devtools.BreakpointInfo):
+ (devtools.BreakpointInfo.prototype.getLine):
+ (devtools.BreakpointInfo.prototype.getV8Id):
+ (devtools.BreakpointInfo.prototype.setV8Id):
+ (devtools.BreakpointInfo.prototype.markAsRemoved):
+ (devtools.BreakpointInfo.prototype.isRemoved):
+ (devtools.CallFrame):
+ (devtools.CallFrame.prototype.evaluate_):
+ (devtools.DebugCommand):
+ (devtools.DebugCommand.prototype.getSequenceNumber):
+ (devtools.DebugCommand.prototype.toJSONProtocol):
+ (devtools.DebuggerMessage):
+ (devtools.DebuggerMessage.prototype.getType):
+ (devtools.DebuggerMessage.prototype.getEvent):
+ (devtools.DebuggerMessage.prototype.getCommand):
+ (devtools.DebuggerMessage.prototype.getRequestSeq):
+ (devtools.DebuggerMessage.prototype.isRunning):
+ (devtools.DebuggerMessage.prototype.isSuccess):
+ (devtools.DebuggerMessage.prototype.getMessage):
+ (devtools.DebuggerMessage.prototype.getBody):
+ (devtools.DebuggerMessage.prototype.lookup):
+ * src/js/DevTools.js: Added.
+ (devtools.dispatch):
+ (devtools.ToolsAgent):
+ (devtools.ToolsAgent.prototype.reset):
+ (devtools.ToolsAgent.prototype.evaluateJavaScript):
+ (devtools.ToolsAgent.prototype.getDebuggerAgent):
+ (devtools.ToolsAgent.prototype.getProfilerAgent):
+ (devtools.ToolsAgent.prototype.frameNavigate_):
+ (devtools.ToolsAgent.prototype.dispatchOnClient_):
+ (devtools.ToolsAgent.prototype.evaluate):
+ (WebInspector.setResourcesPanelEnabled):
+ (debugPrint):
+ (devtools):
+ (WebInspector.loaded):
+ ():
+ (WebInspector.ScriptView.prototype.setupSourceFrameIfNeeded):
+ (WebInspector.ScriptView.prototype.didResolveScriptSource_):
+ (WebInspector.UnresolvedPropertyValue):
+ (WebInspector.UIString):
+ (WebInspector.resourceTrackingWasEnabled):
+ (WebInspector.resourceTrackingWasDisabled):
+ (WebInspector.TestController.prototype.runAfterPendingDispatches):
+ (WebInspector.queuesAreEmpty):
+ (WebInspector.pausedScript):
+ * src/js/DevToolsHostStub.js: Added.
+ (.RemoteDebuggerAgentStub):
+ (.RemoteDebuggerAgentStub.prototype.getContextId):
+ (.RemoteProfilerAgentStub):
+ (.RemoteProfilerAgentStub.prototype.getActiveProfilerModules):
+ (.RemoteProfilerAgentStub.prototype.getLogLines):
+ (.RemoteToolsAgentStub):
+ (.RemoteToolsAgentStub.prototype.dispatchOnInjectedScript):
+ (.RemoteToolsAgentStub.prototype.dispatchOnInspectorController):
+ (.RemoteToolsAgentStub.prototype.executeVoidJavaScript):
+ (.ProfilerStubHelper):
+ (.ProfilerStubHelper.GetInstance):
+ (.ProfilerStubHelper.prototype.StopProfiling):
+ (.ProfilerStubHelper.prototype.StartProfiling):
+ (.ProfilerStubHelper.prototype.getActiveProfilerModules):
+ (.ProfilerStubHelper.prototype.getLogLines):
+ (.RemoteDebuggerCommandExecutorStub):
+ (.RemoteDebuggerCommandExecutorStub.prototype.DebuggerCommand):
+ (.RemoteDebuggerCommandExecutorStub.prototype.DebuggerPauseScript):
+ (.RemoteDebuggerCommandExecutorStub.prototype.sendResponse_):
+ (.DevToolsHostStub):
+ (.DevToolsHostStub.prototype.reset):
+ (.DevToolsHostStub.prototype.setting):
+ (.DevToolsHostStub.prototype.setSetting):
+ * src/js/HeapProfilerPanel.js: Added.
+ (WebInspector.ProfilesPanel.prototype.addSnapshot):
+ (WebInspector.HeapSnapshotView):
+ (WebInspector.HeapSnapshotView.prototype.get statusBarItems):
+ (WebInspector.HeapSnapshotView.prototype.get profile):
+ (WebInspector.HeapSnapshotView.prototype.set profile):
+ (WebInspector.HeapSnapshotView.prototype.show):
+ (WebInspector.HeapSnapshotView.prototype.hide):
+ (WebInspector.HeapSnapshotView.prototype.resize):
+ (WebInspector.HeapSnapshotView.prototype.refresh):
+ (WebInspector.HeapSnapshotView.prototype.refreshShowAsPercents):
+ (WebInspector.HeapSnapshotView.prototype._deleteSearchMatchedFlags):
+ (WebInspector.HeapSnapshotView.prototype.searchCanceled):
+ (WebInspector.HeapSnapshotView.prototype.performSearch):
+ (WebInspector.HeapSnapshotView.prototype.jumpToFirstSearchResult.WebInspector.CPUProfileView.prototype.jumpToFirstSearchResult.jumpToLastSearchResult.WebInspector.CPUProfileView.prototype.jumpToLastSearchResult.jumpToNextSearchResult.WebInspector.CPUProfileView.prototype.jumpToNextSearchResult.jumpToPreviousSearchResult.WebInspector.CPUProfileView.prototype.jumpToPreviousSearchResult.showingFirstSearchResult.WebInspector.CPUProfileView.prototype.showingFirstSearchResult.showingLastSearchResult.WebInspector.CPUProfileView.prototype.showingLastSearchResult._jumpToSearchResult.WebInspector.CPUProfileView.prototype._jumpToSearchResult.refreshVisibleData):
+ (WebInspector.HeapSnapshotView.prototype._changeBase):
+ (WebInspector.HeapSnapshotView.prototype._createSnapshotDataGridList):
+ (WebInspector.HeapSnapshotView.prototype._mouseDownInDataGrid):
+ (WebInspector.HeapSnapshotView.prototype.get _isShowingAsPercent):
+ (WebInspector.HeapSnapshotView.prototype._percentClicked):
+ (WebInspector.HeapSnapshotView.prototype._resetDataGridList):
+ (WebInspector.HeapSnapshotView.prototype._sortData):
+ (WebInspector.HeapSnapshotView.prototype._updateBaseOptions):
+ (WebInspector.HeapSnapshotView.prototype._updatePercentButton):
+ (WebInspector.HeapSnapshotView.prototype._updateSummaryGraph):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.LESS):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.LESS_OR_EQUAL):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.EQUAL):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.GREATER_OR_EQUAL):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.GREATER):
+ (WebInspector.HeapSnapshotView.SearchHelper.parseOperationAndNumber):
+ (WebInspector.HeapSummaryCalculator):
+ (WebInspector.HeapSummaryCalculator.prototype.computeSummaryValues):
+ (WebInspector.HeapSummaryCalculator.prototype.formatValue):
+ (WebInspector.HeapSummaryCalculator.prototype.get showAsPercent):
+ (WebInspector.HeapSummaryCalculator.prototype.set showAsPercent):
+ (WebInspector.HeapSummaryCountCalculator):
+ (WebInspector.HeapSummaryCountCalculator.prototype._highFromLow):
+ (WebInspector.HeapSummaryCountCalculator.prototype._valueToString):
+ (WebInspector.HeapSummarySizeCalculator):
+ (WebInspector.HeapSummarySizeCalculator.prototype._highFromLow):
+ (WebInspector.HeapSnapshotSidebarTreeElement):
+ (WebInspector.HeapSnapshotSidebarTreeElement.prototype.get mainTitle):
+ (WebInspector.HeapSnapshotSidebarTreeElement.prototype.set mainTitle):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get _hasRetainers):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get _parent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype._populate.if):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype._populate):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.produceDiff):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.sort):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.signForDelta):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.showDeltaAsPercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalCount):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalSize):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get countPercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get sizePercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get countDeltaPercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get sizeDeltaPercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get data):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.createCell):
+ (WebInspector.HeapSnapshotDataGridNode):
+ (WebInspector.HeapSnapshotDataGridList):
+ (WebInspector.HeapSnapshotDataGridList.prototype.appendChild):
+ (WebInspector.HeapSnapshotDataGridList.prototype.insertChild):
+ (WebInspector.HeapSnapshotDataGridList.prototype.removeChildren):
+ (WebInspector.HeapSnapshotDataGridList.prototype.populateChildren):
+ (WebInspector.HeapSnapshotDataGridList.propertyComparator.comparator):
+ (WebInspector.HeapSnapshotDataGridList.propertyComparator):
+ (WebInspector.HeapSnapshotDataGridRetainerNode):
+ (WebInspector.HeapSnapshotDataGridRetainerNode.prototype.get sizePercent):
+ (WebInspector.HeapSnapshotDataGridRetainerNode.prototype.get sizeDeltaPercent):
+ (WebInspector.HeapSnapshotDataGridRetainerNode.prototype._calculateRetainers):
+ (WebInspector.HeapSnapshotProfileType):
+ (WebInspector.HeapSnapshotProfileType.prototype.get buttonTooltip):
+ (WebInspector.HeapSnapshotProfileType.prototype.get buttonStyle):
+ (WebInspector.HeapSnapshotProfileType.prototype.buttonClicked):
+ (WebInspector.HeapSnapshotProfileType.prototype.get welcomeMessage):
+ (WebInspector.HeapSnapshotProfileType.prototype.createSidebarTreeElementForProfile):
+ (WebInspector.HeapSnapshotProfileType.prototype.createView):
+ ():
+ * src/js/InjectDispatch.js: Added.
+ (InspectorControllerDispatcher.dispatch):
+ (ApuAgentDispatcher.dispatchToApu):
+ (dispatch):
+ (devtools):
+ * src/js/InspectorControllerImpl.js: Added.
+ (devtools.InspectorBackendImpl):
+ (devtools.InspectorBackendImpl.prototype.toggleNodeSearch):
+ (devtools.InspectorBackendImpl.prototype.debuggerEnabled):
+ (devtools.InspectorBackendImpl.prototype.profilerEnabled):
+ (devtools.InspectorBackendImpl.prototype.addBreakpoint):
+ (devtools.InspectorBackendImpl.prototype.removeBreakpoint):
+ (devtools.InspectorBackendImpl.prototype.updateBreakpoint):
+ (devtools.InspectorBackendImpl.prototype.pauseInDebugger):
+ (devtools.InspectorBackendImpl.prototype.resumeDebugger):
+ (devtools.InspectorBackendImpl.prototype.stepIntoStatementInDebugger):
+ (devtools.InspectorBackendImpl.prototype.stepOutOfFunctionInDebugger):
+ (devtools.InspectorBackendImpl.prototype.stepOverStatementInDebugger):
+ (devtools.InspectorBackendImpl.prototype.setPauseOnExceptionsState):
+ (devtools.InspectorBackendImpl.prototype.pauseOnExceptionsState):
+ (devtools.InspectorBackendImpl.prototype.pauseOnExceptions):
+ (devtools.InspectorBackendImpl.prototype.setPauseOnExceptions):
+ (devtools.InspectorBackendImpl.prototype.startProfiling):
+ (devtools.InspectorBackendImpl.prototype.stopProfiling):
+ (devtools.InspectorBackendImpl.prototype.getProfileHeaders):
+ (devtools.InspectorBackendImpl.prototype.addFullProfile):
+ (devtools.InspectorBackendImpl.prototype.getProfile):
+ (devtools.InspectorBackendImpl.prototype.takeHeapSnapshot):
+ (devtools.InspectorBackendImpl.prototype.dispatchOnInjectedScript):
+ (devtools.InspectorBackendImpl.prototype.installInspectorControllerDelegate_):
+ (devtools.InspectorBackendImpl.prototype.callInspectorController_):
+ * src/js/ProfilerAgent.js: Added.
+ (devtools.ProfilerAgent):
+ (devtools.ProfilerAgent.prototype.setupProfilerProcessorCallbacks):
+ (devtools.ProfilerAgent.prototype.initializeProfiling):
+ (devtools.ProfilerAgent.prototype.startProfiling):
+ (devtools.ProfilerAgent.prototype.stopProfiling):
+ (devtools.ProfilerAgent.prototype.didGetActiveProfilerModules_):
+ (devtools.ProfilerAgent.prototype.didGetLogLines_):
+ * src/js/ProfilerProcessor.js: Added.
+ (devtools.profiler.WebKitViewBuilder):
+ (devtools.profiler.WebKitViewBuilder.prototype.createViewNode):
+ (devtools.profiler.WebKitViewNode):
+ (set get devtools.profiler.WebKitViewNode.prototype.initFuncInfo_):
+ (devtools.profiler.JsProfile):
+ (devtools.profiler.JsProfile.prototype.skipThisFunction):
+ (devtools.profiler.Processor):
+ (devtools.profiler.Processor.prototype.printError):
+ (devtools.profiler.Processor.prototype.skipDispatch):
+ (devtools.profiler.Processor.prototype.setCallbacks):
+ (devtools.profiler.Processor.prototype.setNewProfileCallback):
+ (devtools.profiler.Processor.prototype.processProfiler_.switch.break):
+ (devtools.profiler.Processor.prototype.processProfiler_):
+ (devtools.profiler.Processor.prototype.processCodeCreation_):
+ (devtools.profiler.Processor.prototype.processCodeMove_):
+ (devtools.profiler.Processor.prototype.processCodeDelete_):
+ (devtools.profiler.Processor.prototype.processFunctionCreation_):
+ (devtools.profiler.Processor.prototype.processFunctionMove_):
+ (devtools.profiler.Processor.prototype.processFunctionDelete_):
+ (devtools.profiler.Processor.prototype.processTick_):
+ (devtools.profiler.Processor.prototype.processTickV2_):
+ (devtools.profiler.Processor.prototype.processHeapSampleBegin_):
+ (devtools.profiler.Processor.prototype.processHeapSampleStats_):
+ (devtools.profiler.Processor.prototype.processHeapSampleItem_):
+ (devtools.profiler.Processor.prototype.processHeapJsConsItem_):
+ (devtools.profiler.Processor.prototype.processHeapJsRetItem_.mergeRetainers):
+ (devtools.profiler.Processor.prototype.processHeapJsRetItem_):
+ (devtools.profiler.Processor.prototype.processHeapSampleEnd_):
+ (devtools.profiler.Processor.prototype.createProfileForView):
+ * src/js/Tests.js: Added.
+ (.TestSuite):
+ (.TestSuite.prototype.fail):
+ (.TestSuite.prototype.assertEquals):
+ (.TestSuite.prototype.assertTrue):
+ (.TestSuite.prototype.assertContains):
+ (.TestSuite.prototype.takeControl):
+ (.TestSuite.prototype.releaseControl):
+ (.TestSuite.prototype.reportOk_):
+ (.TestSuite.prototype.reportFailure_):
+ (.TestSuite.prototype.runTest):
+ (.TestSuite.prototype.showPanel):
+ (.TestSuite.prototype.addSniffer.receiver.methodName):
+ (.TestSuite.prototype.addSniffer):
+ (.TestSuite.prototype.testHostIsPresent):
+ (.TestSuite.prototype.testElementsTreeRoot):
+ (.TestSuite.prototype.testMainResource):
+ (.TestSuite.prototype.testResourceContentLength.this.addSniffer.):
+ (.TestSuite.prototype.testResourceHeaders):
+ (.TestSuite.prototype.testCachedResourceMimeType.this.addSniffer.):
+ (.TestSuite.prototype.testCachedResourceMimeType):
+ (.TestSuite.prototype.testProfilerTab):
+ (.TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh.waitUntilScriptIsParsed):
+ (.TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh.checkScriptsPanel):
+ (.TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh):
+ (.TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch.switchToElementsTab):
+ (.TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch.switchToScriptsTab):
+ (.TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch.checkScriptsPanel):
+ (.TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch.checkNoDuplicates):
+ (.TestSuite.prototype.testPauseOnException):
+ (.TestSuite.prototype.testPauseWhenLoadingDevTools):
+ (.TestSuite.prototype.testPauseWhenScriptIsRunning.testScriptPauseAfterDelay):
+ (.TestSuite.prototype.testPauseWhenScriptIsRunning.testScriptPause):
+ (.TestSuite.prototype.testPauseWhenScriptIsRunning):
+ (.TestSuite.prototype.optionsToString_):
+ (.TestSuite.prototype.evaluateInConsole_):
+ (.TestSuite.prototype.waitForSetBreakpointResponse_):
+ (.TestSuite.prototype.testEvalOnCallFrame.setBreakpointCallback):
+ (.TestSuite.prototype.testEvalOnCallFrame.waitForBreakpointHit):
+ (.TestSuite.prototype.testCompletionOnPause):
+ (.TestSuite.prototype.testCompletionOnPause.testLocalsCompletion):
+ (.TestSuite.prototype.testCompletionOnPause.testThisCompletion):
+ (.TestSuite.prototype.testCompletionOnPause.testFieldCompletion):
+ (.TestSuite.prototype.testCompletionOnPause.checkCompletions):
+ (.TestSuite.prototype.testAutoContinueOnSyntaxError.checkScriptsList):
+ (.TestSuite.prototype.testAutoContinueOnSyntaxError.waitForExceptionEvent.test):
+ (.TestSuite.prototype.testAutoContinueOnSyntaxError.waitForExceptionEvent):
+ (.TestSuite.prototype._checkExecutionLine):
+ (.TestSuite.prototype._scriptsAreParsed):
+ (.TestSuite.prototype._waitForScriptPause):
+ (.TestSuite.prototype._checkSourceFrameWhenLoaded.checkExecLine):
+ (.TestSuite.prototype._checkSourceFrameWhenLoaded):
+ (.TestSuite.prototype._performSteps.doNextAction):
+ (.TestSuite.prototype._performSteps):
+ (.TestSuite.prototype._executeCodeWhenScriptsAreParsed.executeFunctionInInspectedPage):
+ (.TestSuite.prototype._waitUntilScriptsAreParsed.waitForAllScripts):
+ (.TestSuite.prototype._waitUntilScriptsAreParsed):
+ (.TestSuite.prototype._executeFunctionForStepTest):
+ (.TestSuite.prototype.testStepOver):
+ (.TestSuite.prototype.testStepOut):
+ (.TestSuite.prototype.testStepIn):
+ (.TestSuite.prototype._evaluateXpath):
+ (.TestSuite.prototype._findNode):
+ (.TestSuite.prototype._findText):
+ (.TestSuite.prototype._nodeIterator):
+ (.TestSuite.prototype._checkScopeSectionDiv):
+ (.TestSuite.prototype._expandScopeSections.updateListener):
+ (.TestSuite.prototype._expandScopeSections):
+ (.TestSuite.prototype.testExpandScope):
+ (.TestSuite.prototype.testExpandScope.examineScopes):
+ (.TestSuite.prototype._findChildProperty):
+ (.TestSuite.prototype._hookGetPropertiesCallback.accessor.getProperties):
+ (.TestSuite.prototype._hookGetPropertiesCallback.try):
+ (.TestSuite.prototype._hookGetPropertiesCallback):
+ (.TestSuite.prototype.testDebugIntrinsicProperties.expandLocalScope):
+ (.TestSuite.prototype.testDebugIntrinsicProperties):
+ (.TestSuite.prototype.testDebugIntrinsicProperties.expandAndCheckNextProperty):
+ (.TestSuite.prototype.testDebugIntrinsicProperties.checkProperty):
+ (.TestSuite.createKeyEvent):
+ (.TestSuite.prototype.testConsoleLog.assertNext):
+ (.TestSuite.prototype.testConsoleLog):
+ (.TestSuite.prototype.testEvalGlobal.initEval):
+ (.TestSuite.prototype.testEvalGlobal):
+ (.TestSuite.prototype.testShowStoragePanel.this.addSniffer.):
+ (.TestSuite.prototype.testShowStoragePanel.this.addSniffer):
+ (.uiTests.runAllTests):
+ (.uiTests.runTest):
+
+2010-02-09 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Upstream JavaScript part of DevTools WebKit API implementation
+
+ https://bugs.webkit.org/show_bug.cgi?id=34744
+
+ * WebKit.gypi: Added.
+ * src/js/DebuggerAgent.js: Added.
+ (devtools.DebuggerAgent):
+ (devtools.DebuggerAgent.prototype.reset):
+ (devtools.DebuggerAgent.prototype.initUI):
+ (devtools.DebuggerAgent.prototype.resolveScriptSource.this.requestSeqToCallback_.cmd.getSequenceNumber):
+ (devtools.DebuggerAgent.prototype.resolveScriptSource):
+ (devtools.DebuggerAgent.prototype.pauseExecution):
+ (devtools.DebuggerAgent.prototype.addBreakpoint):
+ (devtools.DebuggerAgent.prototype.removeBreakpoint):
+ (devtools.DebuggerAgent.prototype.updateBreakpoint):
+ (devtools.DebuggerAgent.prototype.stepIntoStatement):
+ (devtools.DebuggerAgent.prototype.stepOutOfFunction):
+ (devtools.DebuggerAgent.prototype.stepOverStatement):
+ (devtools.DebuggerAgent.prototype.resumeExecution):
+ (devtools.DebuggerAgent.prototype.createExceptionMessage_):
+ (devtools.DebuggerAgent.prototype.showPendingExceptionMessage_):
+ (devtools.DebuggerAgent.prototype.clearExceptionMessage_):
+ (devtools.DebuggerAgent.prototype.pauseOnExceptions):
+ (devtools.DebuggerAgent.prototype.setPauseOnExceptions):
+ (devtools.DebuggerAgent.prototype.requestEvaluate):
+ (devtools.DebuggerAgent.prototype.resolveChildren):
+ (devtools.DebuggerAgent.prototype.resolveScope.this.requestSeqToCallback_.cmd.getSequenceNumber):
+ (devtools.DebuggerAgent.prototype.resolveScope):
+ (devtools.DebuggerAgent.prototype.resolveFrameVariables_.scopeResponseHandler):
+ (devtools.DebuggerAgent.prototype.resolveFrameVariables_):
+ (devtools.DebuggerAgent.prototype.resolveCompletionsOnFrame):
+ (devtools.DebuggerAgent.prototype.getScriptContextType):
+ (devtools.DebuggerAgent.prototype.requestClearBreakpoint_):
+ (devtools.DebuggerAgent.prototype.requestChangeBreakpoint_):
+ (devtools.DebuggerAgent.prototype.requestBacktrace_):
+ (devtools.DebuggerAgent.sendCommand_):
+ (devtools.DebuggerAgent.prototype.stepCommand_):
+ (devtools.DebuggerAgent.prototype.requestLookup_):
+ (devtools.DebuggerAgent.prototype.setContextId_.this.requestSeqToCallback_.cmd.getSequenceNumber):
+ (devtools.DebuggerAgent.prototype.setContextId_):
+ (devtools.DebuggerAgent.prototype.handleDebuggerOutput_):
+ (devtools.DebuggerAgent.prototype.handleBreakEvent_):
+ (devtools.DebuggerAgent.prototype.handleExceptionEvent_):
+ (devtools.DebuggerAgent.prototype.handleScriptsResponse_):
+ (devtools.DebuggerAgent.prototype.isScriptFromInspectedContext_):
+ (devtools.DebuggerAgent.prototype.handleSetBreakpointResponse_):
+ (devtools.DebuggerAgent.prototype.handleAfterCompileEvent_):
+ (devtools.DebuggerAgent.prototype.addScriptInfo_):
+ (devtools.DebuggerAgent.prototype.handleClearBreakpointResponse_):
+ (devtools.DebuggerAgent.prototype.handleBacktraceResponse_):
+ (devtools.DebuggerAgent.prototype.doHandleBacktraceResponse_):
+ (devtools.DebuggerAgent.prototype.evaluateInCallFrame):
+ (devtools.DebuggerAgent.prototype.invokeCallbackForResponse_):
+ (devtools.DebuggerAgent.prototype.formatCallFrame_):
+ (devtools.DebuggerAgent.formatObjectProperties_):
+ (devtools.DebuggerAgent.propertiesToProxies_):
+ (devtools.DebuggerAgent.formatObjectProxy_):
+ (devtools.DebuggerAgent.webkitToV8LineNumber_):
+ (devtools.DebuggerAgent.v8ToWwebkitLineNumber_):
+ (devtools.ScriptInfo):
+ (devtools.ScriptInfo.prototype.getLineOffset):
+ (devtools.ScriptInfo.prototype.getContextType):
+ (devtools.ScriptInfo.prototype.getUrl):
+ (devtools.ScriptInfo.prototype.isUnresolved):
+ (devtools.ScriptInfo.prototype.getBreakpointInfo):
+ (devtools.ScriptInfo.prototype.addBreakpointInfo):
+ (devtools.ScriptInfo.prototype.removeBreakpointInfo):
+ (devtools.BreakpointInfo):
+ (devtools.BreakpointInfo.prototype.getLine):
+ (devtools.BreakpointInfo.prototype.getV8Id):
+ (devtools.BreakpointInfo.prototype.setV8Id):
+ (devtools.BreakpointInfo.prototype.markAsRemoved):
+ (devtools.BreakpointInfo.prototype.isRemoved):
+ (devtools.CallFrame):
+ (devtools.CallFrame.prototype.evaluate_):
+ (devtools.DebugCommand):
+ (devtools.DebugCommand.prototype.getSequenceNumber):
+ (devtools.DebugCommand.prototype.toJSONProtocol):
+ (devtools.DebuggerMessage):
+ (devtools.DebuggerMessage.prototype.getType):
+ (devtools.DebuggerMessage.prototype.getEvent):
+ (devtools.DebuggerMessage.prototype.getCommand):
+ (devtools.DebuggerMessage.prototype.getRequestSeq):
+ (devtools.DebuggerMessage.prototype.isRunning):
+ (devtools.DebuggerMessage.prototype.isSuccess):
+ (devtools.DebuggerMessage.prototype.getMessage):
+ (devtools.DebuggerMessage.prototype.getBody):
+ (devtools.DebuggerMessage.prototype.lookup):
+ * src/js/DevTools.js: Added.
+ (devtools.dispatch):
+ (devtools.ToolsAgent):
+ (devtools.ToolsAgent.prototype.reset):
+ (devtools.ToolsAgent.prototype.evaluateJavaScript):
+ (devtools.ToolsAgent.prototype.getDebuggerAgent):
+ (devtools.ToolsAgent.prototype.getProfilerAgent):
+ (devtools.ToolsAgent.prototype.frameNavigate_):
+ (devtools.ToolsAgent.prototype.dispatchOnClient_):
+ (devtools.ToolsAgent.prototype.evaluate):
+ (WebInspector.setResourcesPanelEnabled):
+ (debugPrint):
+ (devtools):
+ (WebInspector.loaded):
+ ():
+ (WebInspector.ScriptView.prototype.setupSourceFrameIfNeeded):
+ (WebInspector.ScriptView.prototype.didResolveScriptSource_):
+ (WebInspector.UnresolvedPropertyValue):
+ (WebInspector.UIString):
+ (WebInspector.resourceTrackingWasEnabled):
+ (WebInspector.resourceTrackingWasDisabled):
+ (WebInspector.TestController.prototype.runAfterPendingDispatches):
+ (WebInspector.queuesAreEmpty):
+ (WebInspector.pausedScript):
+ * src/js/DevToolsHostStub.js: Added.
+ (.RemoteDebuggerAgentStub):
+ (.RemoteDebuggerAgentStub.prototype.getContextId):
+ (.RemoteProfilerAgentStub):
+ (.RemoteProfilerAgentStub.prototype.getActiveProfilerModules):
+ (.RemoteProfilerAgentStub.prototype.getLogLines):
+ (.RemoteToolsAgentStub):
+ (.RemoteToolsAgentStub.prototype.dispatchOnInjectedScript):
+ (.RemoteToolsAgentStub.prototype.dispatchOnInspectorController):
+ (.RemoteToolsAgentStub.prototype.executeVoidJavaScript):
+ (.ProfilerStubHelper):
+ (.ProfilerStubHelper.GetInstance):
+ (.ProfilerStubHelper.prototype.StopProfiling):
+ (.ProfilerStubHelper.prototype.StartProfiling):
+ (.ProfilerStubHelper.prototype.getActiveProfilerModules):
+ (.ProfilerStubHelper.prototype.getLogLines):
+ (.RemoteDebuggerCommandExecutorStub):
+ (.RemoteDebuggerCommandExecutorStub.prototype.DebuggerCommand):
+ (.RemoteDebuggerCommandExecutorStub.prototype.DebuggerPauseScript):
+ (.RemoteDebuggerCommandExecutorStub.prototype.sendResponse_):
+ (.DevToolsHostStub):
+ (.DevToolsHostStub.prototype.reset):
+ (.DevToolsHostStub.prototype.setting):
+ (.DevToolsHostStub.prototype.setSetting):
+ * src/js/HeapProfilerPanel.js: Added.
+ (WebInspector.ProfilesPanel.prototype.addSnapshot):
+ (WebInspector.HeapSnapshotView):
+ (WebInspector.HeapSnapshotView.prototype.get statusBarItems):
+ (WebInspector.HeapSnapshotView.prototype.get profile):
+ (WebInspector.HeapSnapshotView.prototype.set profile):
+ (WebInspector.HeapSnapshotView.prototype.show):
+ (WebInspector.HeapSnapshotView.prototype.hide):
+ (WebInspector.HeapSnapshotView.prototype.resize):
+ (WebInspector.HeapSnapshotView.prototype.refresh):
+ (WebInspector.HeapSnapshotView.prototype.refreshShowAsPercents):
+ (WebInspector.HeapSnapshotView.prototype._deleteSearchMatchedFlags):
+ (WebInspector.HeapSnapshotView.prototype.searchCanceled):
+ (WebInspector.HeapSnapshotView.prototype.performSearch):
+ (WebInspector.HeapSnapshotView.prototype.jumpToFirstSearchResult.WebInspector.CPUProfileView.prototype.jumpToFirstSearchResult.jumpToLastSearchResult.WebInspector.CPUProfileView.prototype.jumpToLastSearchResult.jumpToNextSearchResult.WebInspector.CPUProfileView.prototype.jumpToNextSearchResult.jumpToPreviousSearchResult.WebInspector.CPUProfileView.prototype.jumpToPreviousSearchResult.showingFirstSearchResult.WebInspector.CPUProfileView.prototype.showingFirstSearchResult.showingLastSearchResult.WebInspector.CPUProfileView.prototype.showingLastSearchResult._jumpToSearchResult.WebInspector.CPUProfileView.prototype._jumpToSearchResult.refreshVisibleData):
+ (WebInspector.HeapSnapshotView.prototype._changeBase):
+ (WebInspector.HeapSnapshotView.prototype._createSnapshotDataGridList):
+ (WebInspector.HeapSnapshotView.prototype._mouseDownInDataGrid):
+ (WebInspector.HeapSnapshotView.prototype.get _isShowingAsPercent):
+ (WebInspector.HeapSnapshotView.prototype._percentClicked):
+ (WebInspector.HeapSnapshotView.prototype._resetDataGridList):
+ (WebInspector.HeapSnapshotView.prototype._sortData):
+ (WebInspector.HeapSnapshotView.prototype._updateBaseOptions):
+ (WebInspector.HeapSnapshotView.prototype._updatePercentButton):
+ (WebInspector.HeapSnapshotView.prototype._updateSummaryGraph):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.LESS):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.LESS_OR_EQUAL):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.EQUAL):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.GREATER_OR_EQUAL):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.GREATER):
+ (WebInspector.HeapSnapshotView.SearchHelper.parseOperationAndNumber):
+ (WebInspector.HeapSummaryCalculator):
+ (WebInspector.HeapSummaryCalculator.prototype.computeSummaryValues):
+ (WebInspector.HeapSummaryCalculator.prototype.formatValue):
+ (WebInspector.HeapSummaryCalculator.prototype.get showAsPercent):
+ (WebInspector.HeapSummaryCalculator.prototype.set showAsPercent):
+ (WebInspector.HeapSummaryCountCalculator):
+ (WebInspector.HeapSummaryCountCalculator.prototype._highFromLow):
+ (WebInspector.HeapSummaryCountCalculator.prototype._valueToString):
+ (WebInspector.HeapSummarySizeCalculator):
+ (WebInspector.HeapSummarySizeCalculator.prototype._highFromLow):
+ (WebInspector.HeapSnapshotSidebarTreeElement):
+ (WebInspector.HeapSnapshotSidebarTreeElement.prototype.get mainTitle):
+ (WebInspector.HeapSnapshotSidebarTreeElement.prototype.set mainTitle):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get _hasRetainers):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get _parent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype._populate.if):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype._populate):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.produceDiff):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.sort):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.signForDelta):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.showDeltaAsPercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalCount):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalSize):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get countPercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get sizePercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get countDeltaPercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get sizeDeltaPercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get data):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.createCell):
+ (WebInspector.HeapSnapshotDataGridNode):
+ (WebInspector.HeapSnapshotDataGridList):
+ (WebInspector.HeapSnapshotDataGridList.prototype.appendChild):
+ (WebInspector.HeapSnapshotDataGridList.prototype.insertChild):
+ (WebInspector.HeapSnapshotDataGridList.prototype.removeChildren):
+ (WebInspector.HeapSnapshotDataGridList.prototype.populateChildren):
+ (WebInspector.HeapSnapshotDataGridList.propertyComparator.comparator):
+ (WebInspector.HeapSnapshotDataGridList.propertyComparator):
+ (WebInspector.HeapSnapshotDataGridRetainerNode):
+ (WebInspector.HeapSnapshotDataGridRetainerNode.prototype.get sizePercent):
+ (WebInspector.HeapSnapshotDataGridRetainerNode.prototype.get sizeDeltaPercent):
+ (WebInspector.HeapSnapshotDataGridRetainerNode.prototype._calculateRetainers):
+ (WebInspector.HeapSnapshotProfileType):
+ (WebInspector.HeapSnapshotProfileType.prototype.get buttonTooltip):
+ (WebInspector.HeapSnapshotProfileType.prototype.get buttonStyle):
+ (WebInspector.HeapSnapshotProfileType.prototype.buttonClicked):
+ (WebInspector.HeapSnapshotProfileType.prototype.get welcomeMessage):
+ (WebInspector.HeapSnapshotProfileType.prototype.createSidebarTreeElementForProfile):
+ (WebInspector.HeapSnapshotProfileType.prototype.createView):
+ ():
+ * src/js/InjectDispatch.js: Added.
+ (InspectorControllerDispatcher.dispatch):
+ (ApuAgentDispatcher.dispatchToApu):
+ (dispatch):
+ (devtools):
+ * src/js/InspectorControllerImpl.js: Added.
+ (devtools.InspectorBackendImpl):
+ (devtools.InspectorBackendImpl.prototype.toggleNodeSearch):
+ (devtools.InspectorBackendImpl.prototype.debuggerEnabled):
+ (devtools.InspectorBackendImpl.prototype.profilerEnabled):
+ (devtools.InspectorBackendImpl.prototype.addBreakpoint):
+ (devtools.InspectorBackendImpl.prototype.removeBreakpoint):
+ (devtools.InspectorBackendImpl.prototype.updateBreakpoint):
+ (devtools.InspectorBackendImpl.prototype.pauseInDebugger):
+ (devtools.InspectorBackendImpl.prototype.resumeDebugger):
+ (devtools.InspectorBackendImpl.prototype.stepIntoStatementInDebugger):
+ (devtools.InspectorBackendImpl.prototype.stepOutOfFunctionInDebugger):
+ (devtools.InspectorBackendImpl.prototype.stepOverStatementInDebugger):
+ (devtools.InspectorBackendImpl.prototype.setPauseOnExceptionsState):
+ (devtools.InspectorBackendImpl.prototype.pauseOnExceptionsState):
+ (devtools.InspectorBackendImpl.prototype.pauseOnExceptions):
+ (devtools.InspectorBackendImpl.prototype.setPauseOnExceptions):
+ (devtools.InspectorBackendImpl.prototype.startProfiling):
+ (devtools.InspectorBackendImpl.prototype.stopProfiling):
+ (devtools.InspectorBackendImpl.prototype.getProfileHeaders):
+ (devtools.InspectorBackendImpl.prototype.addFullProfile):
+ (devtools.InspectorBackendImpl.prototype.getProfile):
+ (devtools.InspectorBackendImpl.prototype.takeHeapSnapshot):
+ (devtools.InspectorBackendImpl.prototype.dispatchOnInjectedScript):
+ (devtools.InspectorBackendImpl.prototype.installInspectorControllerDelegate_):
+ (devtools.InspectorBackendImpl.prototype.callInspectorController_):
+ * src/js/ProfilerAgent.js: Added.
+ (devtools.ProfilerAgent):
+ (devtools.ProfilerAgent.prototype.setupProfilerProcessorCallbacks):
+ (devtools.ProfilerAgent.prototype.initializeProfiling):
+ (devtools.ProfilerAgent.prototype.startProfiling):
+ (devtools.ProfilerAgent.prototype.stopProfiling):
+ (devtools.ProfilerAgent.prototype.didGetActiveProfilerModules_):
+ (devtools.ProfilerAgent.prototype.didGetLogLines_):
+ * src/js/ProfilerProcessor.js: Added.
+ (devtools.profiler.WebKitViewBuilder):
+ (devtools.profiler.WebKitViewBuilder.prototype.createViewNode):
+ (devtools.profiler.WebKitViewNode):
+ (set get devtools.profiler.WebKitViewNode.prototype.initFuncInfo_):
+ (devtools.profiler.JsProfile):
+ (devtools.profiler.JsProfile.prototype.skipThisFunction):
+ (devtools.profiler.Processor):
+ (devtools.profiler.Processor.prototype.printError):
+ (devtools.profiler.Processor.prototype.skipDispatch):
+ (devtools.profiler.Processor.prototype.setCallbacks):
+ (devtools.profiler.Processor.prototype.setNewProfileCallback):
+ (devtools.profiler.Processor.prototype.processProfiler_.switch.break):
+ (devtools.profiler.Processor.prototype.processProfiler_):
+ (devtools.profiler.Processor.prototype.processCodeCreation_):
+ (devtools.profiler.Processor.prototype.processCodeMove_):
+ (devtools.profiler.Processor.prototype.processCodeDelete_):
+ (devtools.profiler.Processor.prototype.processFunctionCreation_):
+ (devtools.profiler.Processor.prototype.processFunctionMove_):
+ (devtools.profiler.Processor.prototype.processFunctionDelete_):
+ (devtools.profiler.Processor.prototype.processTick_):
+ (devtools.profiler.Processor.prototype.processTickV2_):
+ (devtools.profiler.Processor.prototype.processHeapSampleBegin_):
+ (devtools.profiler.Processor.prototype.processHeapSampleStats_):
+ (devtools.profiler.Processor.prototype.processHeapSampleItem_):
+ (devtools.profiler.Processor.prototype.processHeapJsConsItem_):
+ (devtools.profiler.Processor.prototype.processHeapJsRetItem_.mergeRetainers):
+ (devtools.profiler.Processor.prototype.processHeapJsRetItem_):
+ (devtools.profiler.Processor.prototype.processHeapSampleEnd_):
+ (devtools.profiler.Processor.prototype.createProfileForView):
+ * src/js/Tests.js: Added.
+ (.TestSuite):
+ (.TestSuite.prototype.fail):
+ (.TestSuite.prototype.assertEquals):
+ (.TestSuite.prototype.assertTrue):
+ (.TestSuite.prototype.assertContains):
+ (.TestSuite.prototype.takeControl):
+ (.TestSuite.prototype.releaseControl):
+ (.TestSuite.prototype.reportOk_):
+ (.TestSuite.prototype.reportFailure_):
+ (.TestSuite.prototype.runTest):
+ (.TestSuite.prototype.showPanel):
+ (.TestSuite.prototype.addSniffer.receiver.methodName):
+ (.TestSuite.prototype.addSniffer):
+ (.TestSuite.prototype.testHostIsPresent):
+ (.TestSuite.prototype.testElementsTreeRoot):
+ (.TestSuite.prototype.testMainResource):
+ (.TestSuite.prototype.testResourceContentLength.this.addSniffer.):
+ (.TestSuite.prototype.testResourceHeaders):
+ (.TestSuite.prototype.testCachedResourceMimeType.this.addSniffer.):
+ (.TestSuite.prototype.testCachedResourceMimeType):
+ (.TestSuite.prototype.testProfilerTab):
+ (.TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh.waitUntilScriptIsParsed):
+ (.TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh.checkScriptsPanel):
+ (.TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh):
+ (.TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch.switchToElementsTab):
+ (.TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch.switchToScriptsTab):
+ (.TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch.checkScriptsPanel):
+ (.TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch.checkNoDuplicates):
+ (.TestSuite.prototype.testPauseOnException):
+ (.TestSuite.prototype.testPauseWhenLoadingDevTools):
+ (.TestSuite.prototype.testPauseWhenScriptIsRunning.testScriptPauseAfterDelay):
+ (.TestSuite.prototype.testPauseWhenScriptIsRunning.testScriptPause):
+ (.TestSuite.prototype.testPauseWhenScriptIsRunning):
+ (.TestSuite.prototype.optionsToString_):
+ (.TestSuite.prototype.evaluateInConsole_):
+ (.TestSuite.prototype.waitForSetBreakpointResponse_):
+ (.TestSuite.prototype.testEvalOnCallFrame.setBreakpointCallback):
+ (.TestSuite.prototype.testEvalOnCallFrame.waitForBreakpointHit):
+ (.TestSuite.prototype.testCompletionOnPause):
+ (.TestSuite.prototype.testCompletionOnPause.testLocalsCompletion):
+ (.TestSuite.prototype.testCompletionOnPause.testThisCompletion):
+ (.TestSuite.prototype.testCompletionOnPause.testFieldCompletion):
+ (.TestSuite.prototype.testCompletionOnPause.checkCompletions):
+ (.TestSuite.prototype.testAutoContinueOnSyntaxError.checkScriptsList):
+ (.TestSuite.prototype.testAutoContinueOnSyntaxError.waitForExceptionEvent.test):
+ (.TestSuite.prototype.testAutoContinueOnSyntaxError.waitForExceptionEvent):
+ (.TestSuite.prototype._checkExecutionLine):
+ (.TestSuite.prototype._scriptsAreParsed):
+ (.TestSuite.prototype._waitForScriptPause):
+ (.TestSuite.prototype._checkSourceFrameWhenLoaded.checkExecLine):
+ (.TestSuite.prototype._checkSourceFrameWhenLoaded):
+ (.TestSuite.prototype._performSteps.doNextAction):
+ (.TestSuite.prototype._performSteps):
+ (.TestSuite.prototype._executeCodeWhenScriptsAreParsed.executeFunctionInInspectedPage):
+ (.TestSuite.prototype._waitUntilScriptsAreParsed.waitForAllScripts):
+ (.TestSuite.prototype._waitUntilScriptsAreParsed):
+ (.TestSuite.prototype._executeFunctionForStepTest):
+ (.TestSuite.prototype.testStepOver):
+ (.TestSuite.prototype.testStepOut):
+ (.TestSuite.prototype.testStepIn):
+ (.TestSuite.prototype._evaluateXpath):
+ (.TestSuite.prototype._findNode):
+ (.TestSuite.prototype._findText):
+ (.TestSuite.prototype._nodeIterator):
+ (.TestSuite.prototype._checkScopeSectionDiv):
+ (.TestSuite.prototype._expandScopeSections.updateListener):
+ (.TestSuite.prototype._expandScopeSections):
+ (.TestSuite.prototype.testExpandScope):
+ (.TestSuite.prototype.testExpandScope.examineScopes):
+ (.TestSuite.prototype._findChildProperty):
+ (.TestSuite.prototype._hookGetPropertiesCallback.accessor.getProperties):
+ (.TestSuite.prototype._hookGetPropertiesCallback.try):
+ (.TestSuite.prototype._hookGetPropertiesCallback):
+ (.TestSuite.prototype.testDebugIntrinsicProperties.expandLocalScope):
+ (.TestSuite.prototype.testDebugIntrinsicProperties):
+ (.TestSuite.prototype.testDebugIntrinsicProperties.expandAndCheckNextProperty):
+ (.TestSuite.prototype.testDebugIntrinsicProperties.checkProperty):
+ (.TestSuite.createKeyEvent):
+ (.TestSuite.prototype.testConsoleLog.assertNext):
+ (.TestSuite.prototype.testConsoleLog):
+ (.TestSuite.prototype.testEvalGlobal.initEval):
+ (.TestSuite.prototype.testEvalGlobal):
+ (.TestSuite.prototype.testShowStoragePanel.this.addSniffer.):
+ (.TestSuite.prototype.testShowStoragePanel.this.addSniffer):
+ (.uiTests.runAllTests):
+ (.uiTests.runTest):
+
+2010-02-09 Avi Drissman <avi@chromium.org>
+
+ Reviewed by David Levin.
+
+ Chromium Mac: Control-A shouldn't select all/Control-C shouldn't copy
+ https://bugs.webkit.org/show_bug.cgi?id=34615
+
+ * src/WebViewImpl.cpp:
+ (WebKit::WebViewImpl::keyEventDefault):
+
+2010-02-08 Evan Martin <evan@chromium.org>
+
+ dlopen() knows how to search the library search path, so just rely on
+ it. While I'm at it, print out the dlerror() error message on failure.
+
+ [chromium] webgl shouldn't hard code library search path
+ https://bugs.webkit.org/show_bug.cgi?id=34659
+
+ * src/GraphicsContext3D.cpp:
+ (WebCore::GraphicsContext3DInternal::GLConnection::GLConnection):
+ (WebCore::GraphicsContext3DInternal::GLConnection::create):
+
+2010-02-08 Charlie Reis <creis@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ onbeforeunload not called at window close + frame or iframe focused
+ https://bugs.webkit.org/show_bug.cgi?id=27481
+ http://code.google.com/p/chromium/issues/detail?id=32615
+ http://code.google.com/p/chromium/issues/detail?id=17157
+
+ Chromium and WebKit on Windows will now fire beforeunload handlers
+ even if an inner frame is focused.
+
+ Layout tests aren't able to test this bug, since it requires closing
+ the actual browser window, not calling window.close(). Instead,
+ test with WebCore/manual-tests/onbeforeunload-focused-iframe.html.
+
+ * src/WebViewImpl.cpp:
+ (WebKit::WebViewImpl::dispatchBeforeUnloadEvent):
+
+2010-02-08 Pavel Feldman <pfeldman@chromium.org>
+
+ Reviewed by David Levin.
+
+ WebKit/chromium: Custom context menu does not work in inspector.
+ https://bugs.webkit.org/show_bug.cgi?id=34711
+
+ * src/WebDevToolsFrontendImpl.cpp:
+ (WebKit::WebDevToolsFrontendImpl::jsShowContextMenu):
+
+2010-02-08 Nate Chapin <japhet@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Check that the index passed into BackForwardListClientImpl::itemAtIndex()
+ is valid, and return null if it isn't.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34722
+
+ * src/BackForwardListClientImpl.cpp:
+ (WebKit::BackForwardListClientImpl::itemAtIndex):
+
+2010-02-05 Dumitru Daniliuc <dumi@chromium.org>
+
+ Reviewed by Jeremy Orlow.
+
+ Adding a way to close all database handles pointing to a certain
+ database as soon as possible.
+ https://bugs.webkit.org/show_bug.cgi?id=34619
+
+ * public/WebDatabase.h:
+ * src/WebDatabase.cpp:
+ (WebKit::WebDatabase::closeDatabaseImmediately):
+
+2010-02-08 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Nikolas Zimmermann.
+
+ Add back an AffineTransform class for use by SVG
+ https://bugs.webkit.org/show_bug.cgi?id=33750
+
+ Use AffineTransform instead of TransformationMatrix here.
+
+ * tests/TransparencyWinTest.cpp:
+ (WebCore::TEST):
+
+2010-02-07 Jian Li <jianli@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ [chromium] Change chromium interface to handle DownloadURL format.
+ https://bugs.webkit.org/show_bug.cgi?id=34655
+
+ * public/WebDragData.h:
+ * src/WebDragData.cpp:
+ (WebKit::WebDragData::downloadMetadata):
+ (WebKit::WebDragData::setDownloadMetadata):
+
+2010-02-06 Dimitri Glazkov <dglazkov@chromium.org>
+
+ No review, rolling out r54364.
+ http://trac.webkit.org/changeset/54364
+ https://bugs.webkit.org/show_bug.cgi?id=34464
+
+ Introduced asserts in layout tests, needs more testing
+ locally.
+
+ * public/WebViewClient.h:
+ * src/ChromeClientImpl.cpp:
+ * src/ChromeClientImpl.h:
+
+2010-02-05 James Hawkins <jhawkins@chromium.org>
+
+ Reviewed by David Levin.
+
+ [Chromium] Rename autocomplete* to suggestions* to prepare for the
+ refactoring of AutocompletePopupMenuClient.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34664
+
+ * public/WebView.h:
+ * src/AutocompletePopupMenuClient.cpp:
+ (WebKit::AutocompletePopupMenuClient::popupDidHide):
+ * src/EditorClientImpl.cpp:
+ (WebKit::EditorClientImpl::textFieldDidEndEditing):
+ (WebKit::EditorClientImpl::doAutofill):
+ * src/WebViewImpl.cpp:
+ (WebKit::):
+ (WebKit::WebViewImpl::WebViewImpl):
+ (WebKit::WebViewImpl::mouseDown):
+ (WebKit::WebViewImpl::autocompleteHandleKeyEvent):
+ (WebKit::WebViewImpl::setFocus):
+ (WebKit::WebViewImpl::applyAutofillSuggestions):
+ (WebKit::WebViewImpl::hideAutofillPopup):
+ (WebKit::WebViewImpl::hideSuggestionsPopup):
+ (WebKit::WebViewImpl::refreshSuggestionsPopup):
+ * src/WebViewImpl.h:
+ (WebKit::WebViewImpl::suggestionsPopupDidHide):
+
+2010-02-05 James Hawkins <jhawkins@chromium.org>
+
+ Reviewed by David Levin.
+
+ [Chromium] Remove an unused forward declaration in WebKitClient.h.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34622
+
+ * public/WebKitClient.h:
+
+2010-02-05 James Hawkins <jhawkins@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Implement WebInputElement::isActivatedSubmit().
+
+ https://bugs.webkit.org/show_bug.cgi?id=34623
+
+ * public/WebInputElement.h:
+ * src/WebInputElement.cpp:
+ (WebKit::WebInputElement::isActivatedSubmit):
+
+2010-02-05 Nate Chapin <japhet@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Update code for getting a v8::FunctionTemplate.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34606
+
+ * src/WebDevToolsAgentImpl.cpp:
+ (WebKit::WebDevToolsAgentImpl::createInspectorBackendV8Wrapper):
+
+2010-02-05 Mikhail Naganov <mnaganov@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Enable JAVASCRIPT_DEBUGGER in chromium port.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34638
+
+ * features.gypi:
+
+2010-02-04 Yaar Schnitman <yaar@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Upstreaming gtests from chromium: UniscribeHelper and TransparencyWin
+ https://bugs.webkit.org/show_bug.cgi?id=34509
+
+ Resubmit: The previous commit (r54333) was rolled back.
+
+ * WebKit.gyp:
+ * tests/TransparencyWinTest.cpp: Added.
+ (WebCore::RECTToFloatRect):
+ (WebCore::drawNativeRect):
+ (WebCore::getPixelAt):
+ (WebCore::clearTopLayerAlphaChannel):
+ (WebCore::clearTopLayerAlphaPixel):
+ (WebCore::operator<<):
+ (WebCore::TEST):
+ * tests/UniscribeHelperTest.cpp: Added.
+ (WebCore::UniscribeTest::UniscribeTest):
+ (WebCore::UniscribeTest::MakeFont):
+ (WebCore::UniscribeTest::SetUp):
+ (WebCore::UniscribeTest::TearDown):
+ (TEST_F):
+
+2010-02-04 Drew Wilson <atwilson@chromium.org>
+
+ Reviewed by David Levin.
+
+ WorkerContext.close() does not work in the chromium port
+ https://bugs.webkit.org/show_bug.cgi?id=34551
+
+ Test: Adding new downstream test.
+
+ * src/WebWorkerBase.cpp:
+ (WebKit::WebWorkerBase::workerContextClosedTask):
+ Now shuts down the worker thread when WorkerContext::close() is invoked.
+
+2010-02-04 Chris Guillory <chris.guillory@google.com>
+
+ Reviewed by Darin Fisher.
+
+ [Chromium] Add function for AccessibilityObject state change notifications.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34464
+
+ * public/WebViewClient.h:
+ (WebKit::WebViewClient::didChangeAccessibilityObjectState):
+ * src/ChromeClientImpl.cpp:
+ (WebKit::ChromeClientImpl::didChangeAccessibilityObjectState):
+ * src/ChromeClientImpl.h:
+
+2010-02-04 Jeremy Moskovich <jeremy@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Update comments to better document the possible values of the
+ writing direction menu state variables.
+
+ * public/WebContextMenuData.h:
+
+2010-02-04 Nate Chapin <japhet@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Remove references to V8Custom.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32638
+
+ * src/DebuggerAgentImpl.cpp:
+ * src/WebDevToolsFrontendImpl.cpp:
+
2010-02-04 Yury Semikhatsky <yurys@chromium.org>
Unreviewed. Revert 54333 which broke Chromium build.
diff --git a/WebKit/chromium/DEPS b/WebKit/chromium/DEPS
index fc90187..9c45b83 100644
--- a/WebKit/chromium/DEPS
+++ b/WebKit/chromium/DEPS
@@ -35,21 +35,22 @@ vars = {
'chromium_deps_svn': 'http://src.chromium.org/svn/trunk/deps/third_party',
# Dependencies' revisions to use:
- 'chromium_rev': '31834',
- 'google-url_rev': '120',
- 'gtest_rev': '336',
- 'gyp_rev': '751',
- 'icu_rev': '31724',
+ 'chromium_rev': '38580',
+ 'google-url_rev': '121',
+ 'gtest_rev': '359',
+ 'gyp_rev': '781',
+ 'icu_rev': '37341',
'openvcdiff_rev': '28',
- 'ots_rev': '19',
- 'skia_rev': '424',
- 'v8_rev': '3276',
+ 'ots_rev': '26',
+ 'skia_rev': '490',
+ 'v8_rev': '3781',
# Windows:
'cygwin_rev': '11984',
- 'ffmpeg_ia32_rev': '30374',
+ 'ffmpeg_ia32_rev': '34297',
'pthreads-win32_rev': '26716',
'python_24_rev': '22967',
+ 'nss_rev': '36871',
}
deps = {
@@ -142,6 +143,10 @@ deps_os = {
'third_party/pthreads-win32':
Var('chromium_deps_svn')+'/pthreads-win32@'+Var('pthreads-win32_rev'),
+
+ # base.gypi depends on nss on Windows
+ 'third_party/nss':
+ Var('chromium_deps_svn')+'/nss@'+Var('nss_rev'),
},
'unix': {
# Linux, actually.
diff --git a/WebKit/chromium/WebKit.gyp b/WebKit/chromium/WebKit.gyp
index 4f6d3f6..4b0ad2b 100644
--- a/WebKit/chromium/WebKit.gyp
+++ b/WebKit/chromium/WebKit.gyp
@@ -112,6 +112,7 @@
'public/WebEventListener.h',
'public/WebFileChooserCompletion.h',
'public/WebFileChooserParams.h',
+ 'public/WebFileInfo.h',
'public/WebFindOptions.h',
'public/WebFrame.h',
'public/WebFrameClient.h',
@@ -199,6 +200,8 @@
'src/AssertMatchingEnums.cpp',
'src/AutocompletePopupMenuClient.cpp',
'src/AutocompletePopupMenuClient.h',
+ 'src/AutoFillPopupMenuClient.cpp',
+ 'src/AutoFillPopupMenuClient.h',
'src/BackForwardListClientImpl.cpp',
'src/BackForwardListClientImpl.h',
'src/BoundObject.cpp',
@@ -257,6 +260,8 @@
'src/StorageEventDispatcherImpl.h',
'src/StorageNamespaceProxy.cpp',
'src/StorageNamespaceProxy.h',
+ 'src/SuggestionsPopupMenuClient.cpp',
+ 'src/SuggestionsPopupMenuClient.h',
'src/TemporaryGlue.h',
'src/ToolsAgent.h',
'src/WebAccessibilityCache.cpp',
@@ -453,6 +458,14 @@
'tests/KURLTest.cpp',
'tests/RunAllTests.cpp',
],
+ 'conditions': [
+ ['OS=="win"', {
+ 'sources': [
+ 'tests/TransparencyWinTest.cpp',
+ 'tests/UniscribeHelperTest.cpp',
+ ],
+ }],
+ ],
},
], # targets
}
diff --git a/WebKit/chromium/WebKit.gypi b/WebKit/chromium/WebKit.gypi
new file mode 100644
index 0000000..69b1479
--- /dev/null
+++ b/WebKit/chromium/WebKit.gypi
@@ -0,0 +1,67 @@
+#
+# 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.
+#
+
+{
+ 'variables': {
+ # List of DevTools source files, ordered by dependencies. It is used both
+ # for copying them to resource dir, and for generating 'devtools.html' file.
+ 'devtools_js_files': [
+ 'src/js/InspectorControllerImpl.js',
+ 'src/js/DebuggerAgent.js',
+ 'src/js/ProfilerAgent.js',
+ 'src/js/ProfilerProcessor.js',
+ 'src/js/HeapProfilerPanel.js',
+ 'src/js/DevTools.js',
+ 'src/js/DevToolsHostStub.js',
+ 'src/js/Tests.js',
+ ],
+ 'devtools_css_files': [
+ 'src/js/devTools.css',
+ ],
+ 'devtools_image_files': [
+ 'src/js/Images/segmentChromium.png',
+ 'src/js/Images/segmentHoverChromium.png',
+ 'src/js/Images/segmentHoverEndChromium.png',
+ 'src/js/Images/segmentSelectedChromium.png',
+ 'src/js/Images/segmentSelectedEndChromium.png',
+ 'src/js/Images/statusbarBackgroundChromium.png',
+ 'src/js/Images/statusbarBottomBackgroundChromium.png',
+ 'src/js/Images/statusbarButtonsChromium.png',
+ 'src/js/Images/statusbarMenuButtonChromium.png',
+ 'src/js/Images/statusbarMenuButtonSelectedChromium.png',
+ ],
+ },
+}
+
+# Local Variables:
+# tab-width:2
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=2 shiftwidth=2:
diff --git a/WebKit/chromium/features.gypi b/WebKit/chromium/features.gypi
index da2386b..6091b8f 100644
--- a/WebKit/chromium/features.gypi
+++ b/WebKit/chromium/features.gypi
@@ -47,13 +47,14 @@
'ENABLE_DASHBOARD_SUPPORT=0',
'ENABLE_DOM_STORAGE=1',
'ENABLE_GEOLOCATION=1',
- 'ENABLE_JAVASCRIPT_DEBUGGER=0',
+ 'ENABLE_JAVASCRIPT_DEBUGGER=1',
'ENABLE_JSC_MULTIPLE_THREADS=0',
'ENABLE_ICONDATABASE=0',
'ENABLE_INDEXED_DATABASE=1',
'ENABLE_NOTIFICATIONS=1',
'ENABLE_OPENTYPE_SANITIZER=1',
'ENABLE_ORIENTATION_EVENTS=0',
+ 'ENABLE_RUBY=1',
'ENABLE_XHTMLMP=0',
'ENABLE_XSLT=1',
'ENABLE_XPATH=1',
diff --git a/WebKit/chromium/public/WebContextMenuData.h b/WebKit/chromium/public/WebContextMenuData.h
index 049da9c..5d67046 100644
--- a/WebKit/chromium/public/WebContextMenuData.h
+++ b/WebKit/chromium/public/WebContextMenuData.h
@@ -103,7 +103,8 @@ struct WebContextMenuData {
CheckableMenuItemChecked = 0x2,
};
- // Writing direction menu items.
+ // Writing direction menu items - values are unions of
+ // CheckableMenuItemFlags.
// Currently only used on OS X.
int writingDirectionDefault;
int writingDirectionLeftToRight;
diff --git a/WebKit/chromium/public/WebDatabase.h b/WebKit/chromium/public/WebDatabase.h
index 179e828..108201d 100644
--- a/WebKit/chromium/public/WebDatabase.h
+++ b/WebKit/chromium/public/WebDatabase.h
@@ -72,6 +72,8 @@ public:
WEBKIT_API static void updateDatabaseSize(
const WebString& originIdentifier, const WebString& databaseName,
unsigned long long databaseSize, unsigned long long spaceAvailable);
+ WEBKIT_API static void closeDatabaseImmediately(
+ const WebString& originIdentifier, const WebString& databaseName);
#if WEBKIT_IMPLEMENTATION
WebDatabase(const WTF::PassRefPtr<WebCore::Database>&);
diff --git a/WebKit/chromium/public/WebDragData.h b/WebKit/chromium/public/WebDragData.h
index 01582a9..0b861c8 100644
--- a/WebKit/chromium/public/WebDragData.h
+++ b/WebKit/chromium/public/WebDragData.h
@@ -74,6 +74,8 @@ public:
WEBKIT_API WebURL downloadURL() const;
WEBKIT_API void setDownloadURL(const WebURL&);
+ WEBKIT_API WebString downloadMetadata() const;
+ WEBKIT_API void setDownloadMetadata(const WebString&);
WEBKIT_API WebString fileExtension() const;
WEBKIT_API void setFileExtension(const WebString&);
diff --git a/WebKit/chromium/public/WebFileInfo.h b/WebKit/chromium/public/WebFileInfo.h
new file mode 100644
index 0000000..4590a30
--- /dev/null
+++ b/WebKit/chromium/public/WebFileInfo.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#ifndef WebFileInfo_h
+#define WebFileInfo_h
+
+namespace WebKit {
+
+struct WebFileInfo {
+ // The last modification time of the file, in seconds.
+ // The value 0.0 means that the time is not set.
+ double modificationTime;
+
+ WebFileInfo() : modificationTime(0.0) { }
+};
+
+} // namespace WebKit
+
+#endif
diff --git a/WebKit/chromium/public/WebHTTPBody.h b/WebKit/chromium/public/WebHTTPBody.h
index 43f51a6..fcc44ff 100644
--- a/WebKit/chromium/public/WebHTTPBody.h
+++ b/WebKit/chromium/public/WebHTTPBody.h
@@ -32,6 +32,7 @@
#define WebHTTPBody_h
#include "WebData.h"
+#include "WebFileInfo.h"
#include "WebNonCopyable.h"
#include "WebString.h"
@@ -50,6 +51,9 @@ public:
enum { TypeData, TypeFile } type;
WebData data;
WebString filePath;
+ long long fileStart;
+ long long fileLength; // -1 means to the end of the file.
+ WebFileInfo fileInfo;
};
~WebHTTPBody() { reset(); }
@@ -77,7 +81,9 @@ public:
// Append to the list of elements.
WEBKIT_API void appendData(const WebData&);
- WEBKIT_API void appendFile(const WebString&);
+ WEBKIT_API void appendFile(const WebString&); // FIXME: to be removed.
+ // Passing -1 to fileLength means to the end of the file.
+ WEBKIT_API void appendFile(const WebString&, long long fileStart, long long fileLength, const WebFileInfo&);
// Identifies a particular form submission instance. A value of 0 is
// used to indicate an unspecified identifier.
diff --git a/WebKit/chromium/public/WebInputElement.h b/WebKit/chromium/public/WebInputElement.h
index 226624a..59643d1 100644
--- a/WebKit/chromium/public/WebInputElement.h
+++ b/WebKit/chromium/public/WebInputElement.h
@@ -81,11 +81,12 @@ namespace WebKit {
Time,
Week
};
-
+
WEBKIT_API bool autoComplete() const;
WEBKIT_API bool isEnabledFormControl() const;
WEBKIT_API InputType inputType() const;
WEBKIT_API WebString formControlType() const;
+ WEBKIT_API bool isActivatedSubmit() const;
WEBKIT_API void setActivatedSubmit(bool);
WEBKIT_API void setValue(const WebString& value);
WEBKIT_API WebString value() const;
@@ -97,7 +98,6 @@ namespace WebKit {
// storing autofill data. This is either the field name or its id, an empty
// string if it has no name and no id.
WEBKIT_API WebString nameForAutofill() const;
-
};
} // namespace WebKit
diff --git a/WebKit/chromium/public/WebKitClient.h b/WebKit/chromium/public/WebKitClient.h
index fe6c801..fbaa218 100644
--- a/WebKit/chromium/public/WebKitClient.h
+++ b/WebKit/chromium/public/WebKitClient.h
@@ -59,7 +59,6 @@ class WebStorageNamespace;
class WebThemeEngine;
class WebURLLoader;
struct WebCookie;
-struct WebPluginInfo;
template <typename T> class WebVector;
class WebKitClient {
diff --git a/WebKit/chromium/public/WebStorageArea.h b/WebKit/chromium/public/WebStorageArea.h
index 19d98c6..5e2c11c 100644
--- a/WebKit/chromium/public/WebStorageArea.h
+++ b/WebKit/chromium/public/WebStorageArea.h
@@ -45,6 +45,12 @@ class WebStorageArea {
public:
virtual ~WebStorageArea() { }
+ enum Result {
+ ResultOK = 0,
+ ResultBlockedByQuota,
+ ResultBlockedByPolicy
+ };
+
// The number of key/value pairs in the storage area.
virtual unsigned length() = 0;
@@ -57,10 +63,22 @@ public:
// no entry for that key.
virtual WebString getItem(const WebString& key) = 0;
- // Set the value that corresponds to a specific key. QuotaException is set if
- // the StorageArea would have exceeded its quota. The value is NOT set when there's
- // an exception. url is the url that should be used if a storage event fires.
- virtual void setItem(const WebString& key, const WebString& newValue, const WebURL& url, bool& quotaException, WebString& oldValue) = 0;
+ // Set the value that corresponds to a specific key. Result will either be ResultOK
+ // or some particular error. The value is NOT set when there's an error. url is the
+ // url that should be used if a storage event fires.
+ virtual void setItem(const WebString& key, const WebString& newValue, const WebURL& url, Result& result, WebString& oldValue)
+ {
+ bool quotaException = false;
+ setItem(key, newValue, url, quotaException, oldValue);
+ result = quotaException ? ResultBlockedByQuota : ResultOK;
+ }
+ // FIXME: Remove soon (once Chrome has rolled past this revision).
+ virtual void setItem(const WebString& key, const WebString& newValue, const WebURL& url, bool& quotaException, WebString& oldValue)
+ {
+ Result result;
+ setItem(key, newValue, url, result, oldValue);
+ quotaException = result != ResultOK;
+ }
// Remove the value associated with a particular key. url is the url that should be used
// if a storage event fires.
diff --git a/WebKit/chromium/public/WebView.h b/WebKit/chromium/public/WebView.h
index 7b3294f..99125d4 100644
--- a/WebKit/chromium/public/WebView.h
+++ b/WebKit/chromium/public/WebView.h
@@ -223,17 +223,35 @@ public:
virtual WebAccessibilityObject accessibilityObject() = 0;
- // Autofill ------------------------------------------------------------
+ // AutoFill / Autocomplete ---------------------------------------------
- // Notifies the WebView that autofill suggestions are available for a node.
+ // DEPRECATED: WebView::applyAutocompleteSuggestions is the new way to
+ // access this.
virtual void applyAutofillSuggestions(
const WebNode&,
const WebVector<WebString>& suggestions,
int defaultSuggestionIndex) = 0;
- // Hides the autofill popup if any are showing.
+ // Notifies the WebView that AutoFill suggestions are available for a node.
+ virtual void applyAutoFillSuggestions(
+ const WebNode&,
+ const WebVector<WebString>& names,
+ const WebVector<WebString>& labels,
+ int defaultSuggestionIndex) = 0;
+
+ // Notifies the WebView that Autocomplete suggestions are available for a
+ // node.
+ virtual void applyAutocompleteSuggestions(
+ const WebNode&,
+ const WebVector<WebString>& suggestions,
+ int defaultSuggestionIndex) = 0;
+
+ // DEPRECATED: WebView::hideSuggestionsPopup is the new way to access this.
virtual void hideAutofillPopup() = 0;
+ // Hides the suggestions popup if any are showing.
+ virtual void hideSuggestionsPopup() = 0;
+
// Context menu --------------------------------------------------------
diff --git a/WebKit/chromium/public/WebViewClient.h b/WebKit/chromium/public/WebViewClient.h
index 964d382..4d272bb 100644
--- a/WebKit/chromium/public/WebViewClient.h
+++ b/WebKit/chromium/public/WebViewClient.h
@@ -252,6 +252,9 @@ public:
// accessibility object.
virtual void focusAccessibilityObject(const WebAccessibilityObject&) { }
+ // Notifies embedder that the state of an accessibility object has changed.
+ virtual void didChangeAccessibilityObjectState(const WebAccessibilityObject&) { }
+
// Developer tools -----------------------------------------------------
diff --git a/WebKit/chromium/src/AutoFillPopupMenuClient.cpp b/WebKit/chromium/src/AutoFillPopupMenuClient.cpp
new file mode 100644
index 0000000..8e6cab4
--- /dev/null
+++ b/WebKit/chromium/src/AutoFillPopupMenuClient.cpp
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "AutoFillPopupMenuClient.h"
+
+#include "HTMLInputElement.h"
+#include "WebString.h"
+#include "WebVector.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+unsigned AutoFillPopupMenuClient::getSuggestionsCount() const
+{
+ return m_names.size();
+}
+
+WebString AutoFillPopupMenuClient::getSuggestion(unsigned listIndex) const
+{
+ // FIXME: Modify the PopupMenu to add the label in gray right-justified.
+ ASSERT(listIndex >= 0 && listIndex < m_names.size());
+ return m_names[listIndex] + String(" (") + m_labels[listIndex] + String(")");
+}
+
+void AutoFillPopupMenuClient::removeSuggestionAtIndex(unsigned listIndex)
+{
+ // FIXME: Do we want to remove AutoFill suggestions?
+ ASSERT(listIndex >= 0 && listIndex < m_names.size());
+ m_names.remove(listIndex);
+ m_labels.remove(listIndex);
+}
+
+void AutoFillPopupMenuClient::initialize(
+ HTMLInputElement* textField,
+ const WebVector<WebString>& names,
+ const WebVector<WebString>& labels,
+ int defaultSuggestionIndex)
+{
+ ASSERT(names.size() == labels.size());
+ ASSERT(defaultSuggestionIndex < static_cast<int>(names.size()));
+
+ // The suggestions must be set before initializing the
+ // SuggestionsPopupMenuClient.
+ setSuggestions(names, labels);
+
+ SuggestionsPopupMenuClient::initialize(textField, defaultSuggestionIndex);
+}
+
+void AutoFillPopupMenuClient::setSuggestions(const WebVector<WebString>& names,
+ const WebVector<WebString>& labels)
+{
+ ASSERT(names.size() == labels.size());
+
+ m_names.clear();
+ m_labels.clear();
+ for (size_t i = 0; i < names.size(); ++i) {
+ m_names.append(names[i]);
+ m_labels.append(labels[i]);
+ }
+
+ // Try to preserve selection if possible.
+ if (getSelectedIndex() >= static_cast<int>(names.size()))
+ setSelectedIndex(-1);
+}
+
+} // namespace WebKit
diff --git a/WebKit/chromium/src/AutoFillPopupMenuClient.h b/WebKit/chromium/src/AutoFillPopupMenuClient.h
new file mode 100644
index 0000000..fe11334
--- /dev/null
+++ b/WebKit/chromium/src/AutoFillPopupMenuClient.h
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+#ifndef AutoFillPopupMenuClient_h
+#define AutoFillPopupMenuClient_h
+
+#include "SuggestionsPopupMenuClient.h"
+
+namespace WebCore {
+class HTMLInputElement;
+}
+
+namespace WebKit {
+class WebString;
+template <typename T> class WebVector;
+
+// The AutoFill suggestions popup menu client, used to display name suggestions
+// with right-justified labels.
+class AutoFillPopupMenuClient : public SuggestionsPopupMenuClient {
+public:
+ // SuggestionsPopupMenuClient implementation:
+ virtual unsigned getSuggestionsCount() const;
+ virtual WebString getSuggestion(unsigned listIndex) const;
+ virtual void removeSuggestionAtIndex(unsigned listIndex);
+
+ void initialize(WebCore::HTMLInputElement*,
+ const WebVector<WebString>& names,
+ const WebVector<WebString>& labels,
+ int defaultSuggestionIndex);
+
+ void setSuggestions(const WebVector<WebString>& names,
+ const WebVector<WebString>& labels);
+
+private:
+ Vector<WebCore::String> m_names;
+ Vector<WebCore::String> m_labels;
+};
+
+<<<<<<< HEAD:WebCore/bindings/v8/RuntimeEnabledFeatures.cpp
+bool RuntimeEnabledFeatures::isLocalStorageEnabled = true;
+bool RuntimeEnabledFeatures::isSessionStorageEnabled = true;
+bool RuntimeEnabledFeatures::isNotificationsEnabled = false;
+#if PLATFORM(ANDROID)
+// These should default to true, to match the behavior with JSC
+bool RuntimeEnabledFeatures::isApplicationCacheEnabled = true;
+bool RuntimeEnabledFeatures::isGeolocationEnabled = true;
+#endif
+bool RuntimeEnabledFeatures::isIndexedDatabaseEnabled = false;
+=======
+} // namespace WebKit
+>>>>>>> webkit.org at r54731:WebKit/chromium/src/AutoFillPopupMenuClient.h
+
+#endif
diff --git a/WebKit/chromium/src/AutocompletePopupMenuClient.cpp b/WebKit/chromium/src/AutocompletePopupMenuClient.cpp
index 62d4dff..9620ffc 100644
--- a/WebKit/chromium/src/AutocompletePopupMenuClient.cpp
+++ b/WebKit/chromium/src/AutocompletePopupMenuClient.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * 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
@@ -31,27 +31,29 @@
#include "config.h"
#include "AutocompletePopupMenuClient.h"
-#include "CSSStyleSelector.h"
-#include "CSSValueKeywords.h"
-#include "FrameView.h"
#include "HTMLInputElement.h"
-#include "RenderTheme.h"
+#include "WebString.h"
#include "WebVector.h"
-#include "WebViewImpl.h"
using namespace WebCore;
namespace WebKit {
-AutocompletePopupMenuClient::AutocompletePopupMenuClient(WebViewImpl* webView)
- : m_textField(0)
- , m_selectedIndex(0)
- , m_webView(webView)
+unsigned AutocompletePopupMenuClient::getSuggestionsCount() const
{
+ return m_suggestions.size();
}
-AutocompletePopupMenuClient::~AutocompletePopupMenuClient()
+WebString AutocompletePopupMenuClient::getSuggestion(unsigned listIndex) const
{
+ ASSERT(listIndex >= 0 && listIndex < m_suggestions.size());
+ return m_suggestions[listIndex];
+}
+
+void AutocompletePopupMenuClient::removeSuggestionAtIndex(unsigned listIndex)
+{
+ ASSERT(listIndex >= 0 && listIndex < m_suggestions.size());
+ m_suggestions.remove(listIndex);
}
void AutocompletePopupMenuClient::initialize(
@@ -60,90 +62,12 @@ void AutocompletePopupMenuClient::initialize(
int defaultSuggestionIndex)
{
ASSERT(defaultSuggestionIndex < static_cast<int>(suggestions.size()));
- m_textField = textField;
- m_selectedIndex = defaultSuggestionIndex;
- setSuggestions(suggestions);
-
- FontDescription fontDescription;
- m_webView->theme()->systemFont(CSSValueWebkitControl, fontDescription);
- // Use a smaller font size to match IE/Firefox.
- // FIXME: http://crbug.com/7376 use the system size instead of a
- // fixed font size value.
- fontDescription.setComputedSize(12.0);
- Font font(fontDescription, 0, 0);
- font.update(textField->document()->styleSelector()->fontSelector());
- // The direction of text in popup menu is set the same as the direction of
- // the input element: textField.
- m_style.set(new PopupMenuStyle(Color::black, Color::white, font, true,
- Length(WebCore::Fixed),
- textField->renderer()->style()->direction()));
-}
-
-void AutocompletePopupMenuClient::valueChanged(unsigned listIndex, bool fireEvents)
-{
- m_textField->setValue(m_suggestions[listIndex]);
- EditorClientImpl* editor =
- static_cast<EditorClientImpl*>(m_webView->page()->editorClient());
- ASSERT(editor);
- editor->onAutofillSuggestionAccepted(
- static_cast<HTMLInputElement*>(m_textField.get()));
-}
-
-String AutocompletePopupMenuClient::itemText(unsigned listIndex) const
-{
- return m_suggestions[listIndex];
-}
-
-PopupMenuStyle AutocompletePopupMenuClient::itemStyle(unsigned listIndex) const
-{
- return *m_style;
-}
-
-PopupMenuStyle AutocompletePopupMenuClient::menuStyle() const
-{
- return *m_style;
-}
-
-int AutocompletePopupMenuClient::clientPaddingLeft() const
-{
- // Bug http://crbug.com/7708 seems to indicate the style can be 0.
- RenderStyle* style = textFieldStyle();
- return style ? m_webView->theme()->popupInternalPaddingLeft(style) : 0;
-}
-int AutocompletePopupMenuClient::clientPaddingRight() const
-{
- // Bug http://crbug.com/7708 seems to indicate the style can be 0.
- RenderStyle* style = textFieldStyle();
- return style ? m_webView->theme()->popupInternalPaddingRight(style) : 0;
-}
-
-void AutocompletePopupMenuClient::popupDidHide()
-{
- m_webView->autoCompletePopupDidHide();
-}
-
-void AutocompletePopupMenuClient::setTextFromItem(unsigned listIndex)
-{
- m_textField->setValue(m_suggestions[listIndex]);
-}
-
-FontSelector* AutocompletePopupMenuClient::fontSelector() const
-{
- return m_textField->document()->styleSelector()->fontSelector();
-}
-
-HostWindow* AutocompletePopupMenuClient::hostWindow() const
-{
- return m_textField->document()->view()->hostWindow();
-}
+ // The suggestions must be set before initializing the
+ // SuggestionsPopupMenuClient.
+ setSuggestions(suggestions);
-PassRefPtr<Scrollbar> AutocompletePopupMenuClient::createScrollbar(
- ScrollbarClient* client,
- ScrollbarOrientation orientation,
- ScrollbarControlSize size)
-{
- return Scrollbar::createNativeScrollbar(client, orientation, size);
+ SuggestionsPopupMenuClient::initialize(textField, defaultSuggestionIndex);
}
void AutocompletePopupMenuClient::setSuggestions(const WebVector<WebString>& suggestions)
@@ -151,28 +75,10 @@ void AutocompletePopupMenuClient::setSuggestions(const WebVector<WebString>& sug
m_suggestions.clear();
for (size_t i = 0; i < suggestions.size(); ++i)
m_suggestions.append(suggestions[i]);
- // Try to preserve selection if possible.
- if (m_selectedIndex >= static_cast<int>(suggestions.size()))
- m_selectedIndex = -1;
-}
-void AutocompletePopupMenuClient::removeItemAtIndex(int index)
-{
- ASSERT(index >= 0 && index < static_cast<int>(m_suggestions.size()));
- m_suggestions.remove(index);
-}
-
-RenderStyle* AutocompletePopupMenuClient::textFieldStyle() const
-{
- RenderStyle* style = m_textField->computedStyle();
- if (!style) {
- // It seems we can only have a 0 style in a TextField if the
- // node is detached, in which case we the popup shoud not be
- // showing. Please report this in http://crbug.com/7708 and
- // include the page you were visiting.
- ASSERT_NOT_REACHED();
- }
- return style;
+ // Try to preserve selection if possible.
+ if (getSelectedIndex() >= static_cast<int>(suggestions.size()))
+ setSelectedIndex(-1);
}
} // namespace WebKit
diff --git a/WebKit/chromium/src/AutocompletePopupMenuClient.h b/WebKit/chromium/src/AutocompletePopupMenuClient.h
index ad24e54..16a3771 100644
--- a/WebKit/chromium/src/AutocompletePopupMenuClient.h
+++ b/WebKit/chromium/src/AutocompletePopupMenuClient.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * 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
@@ -28,69 +28,38 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "PopupMenuClient.h"
+#ifndef AutocompletePopupMenuClient_h
+#define AutocompletePopupMenuClient_h
+
+#include "SuggestionsPopupMenuClient.h"
namespace WebCore {
class HTMLInputElement;
-class PopupMenuStyle;
-class RenderStyle;
}
namespace WebKit {
class WebString;
-class WebViewImpl;
template <typename T> class WebVector;
-// AutocompletePopupMenuClient
-class AutocompletePopupMenuClient : public WebCore::PopupMenuClient {
+// The Autocomplete suggestions popup menu client, used to display a list of
+// autocomplete suggestions.
+class AutocompletePopupMenuClient : public SuggestionsPopupMenuClient {
public:
- AutocompletePopupMenuClient(WebViewImpl* webview);
- ~AutocompletePopupMenuClient();
+ // SuggestionsPopupMenuClient implementation:
+ virtual unsigned getSuggestionsCount() const;
+ virtual WebString getSuggestion(unsigned listIndex) const;
+ virtual void removeSuggestionAtIndex(unsigned listIndex);
void initialize(WebCore::HTMLInputElement*,
const WebVector<WebString>& suggestions,
int defaultSuggestionIndex);
- WebCore::HTMLInputElement* textField() const { return m_textField.get(); }
-
void setSuggestions(const WebVector<WebString>&);
- void removeItemAtIndex(int index);
-
- // WebCore::PopupMenuClient methods:
- virtual void valueChanged(unsigned listIndex, bool fireEvents = true);
- virtual WebCore::String itemText(unsigned listIndex) const;
- virtual WebCore::String itemToolTip(unsigned lastIndex) const { return WebCore::String(); }
- virtual bool itemIsEnabled(unsigned listIndex) const { return true; }
- virtual WebCore::PopupMenuStyle itemStyle(unsigned listIndex) const;
- virtual WebCore::PopupMenuStyle menuStyle() const;
- virtual int clientInsetLeft() const { return 0; }
- virtual int clientInsetRight() const { return 0; }
- virtual int clientPaddingLeft() const;
- virtual int clientPaddingRight() const;
- virtual int listSize() const { return m_suggestions.size(); }
- virtual int selectedIndex() const { return m_selectedIndex; }
- virtual void popupDidHide();
- virtual bool itemIsSeparator(unsigned listIndex) const { return false; }
- virtual bool itemIsLabel(unsigned listIndex) const { return false; }
- virtual bool itemIsSelected(unsigned listIndex) const { return false; }
- virtual bool shouldPopOver() const { return false; }
- virtual bool valueShouldChangeOnHotTrack() const { return false; }
- virtual void setTextFromItem(unsigned listIndex);
- virtual WebCore::FontSelector* fontSelector() const;
- virtual WebCore::HostWindow* hostWindow() const;
- virtual PassRefPtr<WebCore::Scrollbar> createScrollbar(
- WebCore::ScrollbarClient* client,
- WebCore::ScrollbarOrientation orientation,
- WebCore::ScrollbarControlSize size);
private:
- WebCore::RenderStyle* textFieldStyle() const;
-
- RefPtr<WebCore::HTMLInputElement> m_textField;
Vector<WebCore::String> m_suggestions;
- int m_selectedIndex;
- WebViewImpl* m_webView;
- OwnPtr<WebCore::PopupMenuStyle> m_style;
};
} // namespace WebKit
+
+#endif
diff --git a/WebKit/chromium/src/BackForwardListClientImpl.cpp b/WebKit/chromium/src/BackForwardListClientImpl.cpp
index 8feae32..f5b04ab 100644
--- a/WebKit/chromium/src/BackForwardListClientImpl.cpp
+++ b/WebKit/chromium/src/BackForwardListClientImpl.cpp
@@ -90,7 +90,7 @@ HistoryItem* BackForwardListClientImpl::currentItem()
HistoryItem* BackForwardListClientImpl::itemAtIndex(int index)
{
- if (!m_webView->client())
+ if (!m_webView->client() || index > forwardListCount() || -index > backListCount())
return 0;
// Since we don't keep the entire back/forward list, we have no way to
diff --git a/WebKit/chromium/src/ChromeClientImpl.cpp b/WebKit/chromium/src/ChromeClientImpl.cpp
index 9079094..ce2f00c 100644
--- a/WebKit/chromium/src/ChromeClientImpl.cpp
+++ b/WebKit/chromium/src/ChromeClientImpl.cpp
@@ -659,6 +659,14 @@ void ChromeClientImpl::getPopupMenuInfo(PopupContainer* popupContainer,
info->items.swap(outputItems);
}
+void ChromeClientImpl::didChangeAccessibilityObjectState(AccessibilityObject* obj)
+{
+ // Alert assistive technology about the accessibility object state change
+ if (obj)
+ m_webView->client()->didChangeAccessibilityObjectState(WebAccessibilityObject(obj));
+}
+
+
#if ENABLE(NOTIFICATIONS)
NotificationPresenter* ChromeClientImpl::notificationPresenter() const
{
diff --git a/WebKit/chromium/src/ChromeClientImpl.h b/WebKit/chromium/src/ChromeClientImpl.h
index 5a1e9cc..9e8c2e3 100644
--- a/WebKit/chromium/src/ChromeClientImpl.h
+++ b/WebKit/chromium/src/ChromeClientImpl.h
@@ -34,6 +34,7 @@
#include "ChromeClientChromium.h"
namespace WebCore {
+class AccessibilityObject;
class HTMLParserQuirks;
class PopupContainer;
class SecurityOrigin;
@@ -132,6 +133,7 @@ public:
const WebCore::IntRect& bounds,
bool activatable,
bool handleExternally);
+ virtual void didChangeAccessibilityObjectState(WebCore::AccessibilityObject*);
// ChromeClientImpl:
void setCursor(const WebCursorInfo& cursor);
diff --git a/WebKit/chromium/src/DebuggerAgent.h b/WebKit/chromium/src/DebuggerAgent.h
index cac9686..17cde11 100644
--- a/WebKit/chromium/src/DebuggerAgent.h
+++ b/WebKit/chromium/src/DebuggerAgent.h
@@ -37,7 +37,10 @@ namespace WebKit {
#define DEBUGGER_AGENT_STRUCT(METHOD0, METHOD1, METHOD2, METHOD3, METHOD4, METHOD5) \
/* Requests global context id of the inspected tab. */ \
- METHOD0(getContextId)
+ METHOD0(getContextId) \
+ \
+ /* Request v8 to process all debug commands in the queue. */ \
+ METHOD0(processDebugCommands)
DEFINE_RPC_CLASS(DebuggerAgent, DEBUGGER_AGENT_STRUCT)
diff --git a/WebKit/chromium/src/DebuggerAgentImpl.cpp b/WebKit/chromium/src/DebuggerAgentImpl.cpp
index 0c3d1ea..d592710 100644
--- a/WebKit/chromium/src/DebuggerAgentImpl.cpp
+++ b/WebKit/chromium/src/DebuggerAgentImpl.cpp
@@ -51,7 +51,6 @@ using WebCore::Frame;
using WebCore::Page;
using WebCore::String;
using WebCore::V8ClassIndex;
-using WebCore::V8Custom;
using WebCore::V8DOMWindow;
using WebCore::V8DOMWrapper;
using WebCore::V8Proxy;
@@ -80,6 +79,12 @@ void DebuggerAgentImpl::getContextId()
m_delegate->setContextId(m_webdevtoolsAgent->hostId());
}
+void DebuggerAgentImpl::processDebugCommands()
+{
+ DebuggerAgentManager::UtilityContextScope utilityScope;
+ v8::Debug::ProcessDebugMessages();
+}
+
void DebuggerAgentImpl::debuggerOutput(const String& command)
{
m_delegate->debuggerOutput(command);
@@ -90,13 +95,21 @@ void DebuggerAgentImpl::debuggerOutput(const String& command)
void DebuggerAgentImpl::createUtilityContext(Frame* frame, v8::Persistent<v8::Context>* context)
{
v8::HandleScope scope;
+ bool canExecuteScripts = frame->script()->canExecuteScripts();
// Set up the DOM window as the prototype of the new global object.
v8::Handle<v8::Context> windowContext = V8Proxy::context(frame);
- v8::Handle<v8::Object> windowGlobal = windowContext->Global();
- v8::Handle<v8::Object> windowWrapper = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, windowGlobal);
-
- ASSERT(V8DOMWindow::toNative(windowWrapper) == frame->domWindow());
+ v8::Handle<v8::Object> windowGlobal;
+ v8::Handle<v8::Object> windowWrapper;
+ if (canExecuteScripts) {
+ // FIXME: This check prevents renderer from crashing, while providing limited capabilities for
+ // DOM inspection, Resources tracking, no scripts support, some timeline profiling. Console will
+ // result in exceptions for each evaluation. There is still some work that needs to be done in
+ // order to polish the script-less experience.
+ windowGlobal = windowContext->Global();
+ windowWrapper = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), windowGlobal);
+ ASSERT(V8DOMWindow::toNative(windowWrapper) == frame->domWindow());
+ }
v8::Handle<v8::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New();
@@ -121,11 +134,13 @@ void DebuggerAgentImpl::createUtilityContext(Frame* frame, v8::Persistent<v8::Co
v8::Handle<v8::Object> global = (*context)->Global();
v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__");
- global->Set(implicitProtoString, windowWrapper);
+ if (canExecuteScripts)
+ global->Set(implicitProtoString, windowWrapper);
// Give the code running in the new context a way to get access to the
// original context.
- global->Set(v8::String::New("contentWindow"), windowGlobal);
+ if (canExecuteScripts)
+ global->Set(v8::String::New("contentWindow"), windowGlobal);
}
String DebuggerAgentImpl::executeUtilityFunction(
@@ -180,22 +195,6 @@ String DebuggerAgentImpl::executeUtilityFunction(
return WebCore::toWebCoreStringWithNullCheck(resObj);
}
-void DebuggerAgentImpl::executeVoidJavaScript(v8::Handle<v8::Context> context)
-{
- v8::HandleScope scope;
- ASSERT(!context.IsEmpty());
- v8::Context::Scope contextScope(context);
- DebuggerAgentManager::UtilityContextScope utilityScope;
-
- v8::Handle<v8::Value> function =
- context->Global()->Get(v8::String::New("devtools$$void"));
- ASSERT(function->IsFunction());
- v8::Handle<v8::Value> args[] = {
- v8::Local<v8::Value>()
- };
- v8::Handle<v8::Function>::Cast(function)->Call(context->Global(), 0, args);
-}
-
WebCore::Page* DebuggerAgentImpl::page()
{
return m_webViewImpl->page();
diff --git a/WebKit/chromium/src/DebuggerAgentImpl.h b/WebKit/chromium/src/DebuggerAgentImpl.h
index 65dc14c..6eaf576 100644
--- a/WebKit/chromium/src/DebuggerAgentImpl.h
+++ b/WebKit/chromium/src/DebuggerAgentImpl.h
@@ -62,6 +62,7 @@ public:
// DebuggerAgent implementation.
virtual void getContextId();
+ virtual void processDebugCommands();
void debuggerOutput(const WebCore::String& out);
@@ -81,10 +82,6 @@ public:
bool async,
WebCore::String* exception);
- // Executes a no-op function in the utility context. We don't use
- // executeUtilityFunction for that to avoid script evaluation leading to
- // undesirable AfterCompile events.
- void executeVoidJavaScript(v8::Handle<v8::Context> context);
WebCore::Page* page();
WebDevToolsAgentImpl* webdevtoolsAgent() { return m_webdevtoolsAgent; }
diff --git a/WebKit/chromium/src/EditorClientImpl.cpp b/WebKit/chromium/src/EditorClientImpl.cpp
index e035e6a..d5bddc5 100644
--- a/WebKit/chromium/src/EditorClientImpl.cpp
+++ b/WebKit/chromium/src/EditorClientImpl.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006, 2007 Apple, Inc. All rights reserved.
- * Copyright (C) 2009 Google, Inc. All rights reserved.
+ * 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
@@ -654,7 +654,7 @@ void EditorClientImpl::textFieldDidEndEditing(Element* element)
m_autofillTimer.stop();
// Hide any showing popup.
- m_webView->hideAutoCompletePopup();
+ m_webView->hideSuggestionsPopup();
if (!m_webView->client())
return; // The page is getting closed, don't fill the password.
@@ -748,7 +748,7 @@ void EditorClientImpl::doAutofill(Timer<EditorClientImpl>* timer)
&& inputElement->selectionEnd() == static_cast<int>(value.length());
if ((!args->autofillOnEmptyValue && value.isEmpty()) || !isCaretAtEnd) {
- m_webView->hideAutoCompletePopup();
+ m_webView->hideSuggestionsPopup();
return;
}
diff --git a/WebKit/chromium/src/GraphicsContext3D.cpp b/WebKit/chromium/src/GraphicsContext3D.cpp
index 7fe31b0..83574da 100644
--- a/WebKit/chromium/src/GraphicsContext3D.cpp
+++ b/WebKit/chromium/src/GraphicsContext3D.cpp
@@ -275,14 +275,6 @@ private:
, m_glXGetCurrentContext(getCurrentContext)
{
}
-
- static void* tryLoad(const char* libName)
- {
- // We use RTLD_GLOBAL semantics so that GLEW initialization works;
- // GLEW expects to be able to open the current process's handle
- // and do dlsym's of GL entry points from there.
- return dlopen(libName, RTLD_LAZY | RTLD_GLOBAL);
- }
};
static GLConnection* s_gl;
@@ -304,22 +296,13 @@ GraphicsContext3DInternal::GLConnection* GraphicsContext3DInternal::GLConnection
return 0;
}
- void* libGL = 0;
- const char* libNames[] = {
- "/usr/lib/libGL.so.1",
- "/usr/lib32/libGL.so.1",
- "/usr/lib64/libGL.so.1",
- };
- for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++) {
- libGL = tryLoad(libNames[i]);
- if (libGL)
- break;
- }
+ // We use RTLD_GLOBAL semantics so that GLEW initialization works;
+ // GLEW expects to be able to open the current process's handle
+ // and do dlsym's of GL entry points from there.
+ void* libGL = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL);
if (!libGL) {
- printf("GraphicsContext3D: error opening libGL.so.1\n");
- printf("GraphicsContext3D: tried:\n");
- for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++)
- printf(" %s\n", libNames[i]);
+ XCloseDisplay(dpy);
+ printf("GraphicsContext3D: error opening libGL.so.1: %s\n", dlerror());
return 0;
}
@@ -726,7 +709,6 @@ void GraphicsContext3DInternal::reshape(int width, int height)
#endif // FLIP_FRAMEBUFFER_VERTICALLY
glClear(GL_COLOR_BUFFER_BIT);
- viewportImpl(0, 0, width, height);
#if PLATFORM(CG)
// Need to reallocate the client-side backing store.
diff --git a/WebKit/chromium/src/SuggestionsPopupMenuClient.cpp b/WebKit/chromium/src/SuggestionsPopupMenuClient.cpp
new file mode 100644
index 0000000..b4a77a3
--- /dev/null
+++ b/WebKit/chromium/src/SuggestionsPopupMenuClient.cpp
@@ -0,0 +1,186 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "SuggestionsPopupMenuClient.h"
+
+#include "CSSStyleSelector.h"
+#include "CSSValueKeywords.h"
+#include "Chrome.h"
+#include "FrameView.h"
+#include "HTMLInputElement.h"
+#include "RenderTheme.h"
+#include "WebViewImpl.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+SuggestionsPopupMenuClient::SuggestionsPopupMenuClient()
+ : m_textField(0)
+ , m_selectedIndex(0)
+{
+}
+
+SuggestionsPopupMenuClient::~SuggestionsPopupMenuClient()
+{
+}
+
+// FIXME: Implement this per-derived class?
+void SuggestionsPopupMenuClient::valueChanged(unsigned listIndex, bool fireEvents)
+{
+ m_textField->setValue(getSuggestion(listIndex));
+
+ WebViewImpl* webView = getWebView();
+ if (!webView)
+ return;
+
+ EditorClientImpl* editor =
+ static_cast<EditorClientImpl*>(webView->page()->editorClient());
+ ASSERT(editor);
+ editor->onAutofillSuggestionAccepted(
+ static_cast<HTMLInputElement*>(m_textField.get()));
+}
+
+String SuggestionsPopupMenuClient::itemText(unsigned listIndex) const
+{
+ return getSuggestion(listIndex);
+}
+
+PopupMenuStyle SuggestionsPopupMenuClient::itemStyle(unsigned listIndex) const
+{
+ return *m_style;
+}
+
+PopupMenuStyle SuggestionsPopupMenuClient::menuStyle() const
+{
+ return *m_style;
+}
+
+int SuggestionsPopupMenuClient::clientPaddingLeft() const
+{
+ // Bug http://crbug.com/7708 seems to indicate the style can be 0.
+ RenderStyle* style = textFieldStyle();
+ if (!style)
+ return 0;
+
+ return RenderTheme::defaultTheme()->popupInternalPaddingLeft(style);
+}
+
+int SuggestionsPopupMenuClient::clientPaddingRight() const
+{
+ // Bug http://crbug.com/7708 seems to indicate the style can be 0.
+ RenderStyle* style = textFieldStyle();
+ if (!style)
+ return 0;
+
+ return RenderTheme::defaultTheme()->popupInternalPaddingRight(style);
+}
+
+void SuggestionsPopupMenuClient::popupDidHide()
+{
+ WebViewImpl* webView = getWebView();
+ if (webView)
+ webView->suggestionsPopupDidHide();
+}
+
+void SuggestionsPopupMenuClient::setTextFromItem(unsigned listIndex)
+{
+ m_textField->setValue(getSuggestion(listIndex));
+}
+
+FontSelector* SuggestionsPopupMenuClient::fontSelector() const
+{
+ return m_textField->document()->styleSelector()->fontSelector();
+}
+
+HostWindow* SuggestionsPopupMenuClient::hostWindow() const
+{
+ return m_textField->document()->view()->hostWindow();
+}
+
+PassRefPtr<Scrollbar> SuggestionsPopupMenuClient::createScrollbar(
+ ScrollbarClient* client,
+ ScrollbarOrientation orientation,
+ ScrollbarControlSize size)
+{
+ return Scrollbar::createNativeScrollbar(client, orientation, size);
+}
+
+RenderStyle* SuggestionsPopupMenuClient::textFieldStyle() const
+{
+ RenderStyle* style = m_textField->computedStyle();
+ if (!style) {
+ // It seems we can only have a 0 style in a TextField if the
+ // node is detached, in which case we the popup shoud not be
+ // showing. Please report this in http://crbug.com/7708 and
+ // include the page you were visiting.
+ ASSERT_NOT_REACHED();
+ }
+ return style;
+}
+
+void SuggestionsPopupMenuClient::initialize(HTMLInputElement* textField,
+ int defaultSuggestionIndex)
+{
+ m_textField = textField;
+ m_selectedIndex = defaultSuggestionIndex;
+
+ FontDescription fontDescription;
+ RenderTheme::defaultTheme()->systemFont(CSSValueWebkitControl,
+ fontDescription);
+
+ // Use a smaller font size to match IE/Firefox.
+ // FIXME: http://crbug.com/7376 use the system size instead of a
+ // fixed font size value.
+ fontDescription.setComputedSize(12.0);
+ Font font(fontDescription, 0, 0);
+ font.update(textField->document()->styleSelector()->fontSelector());
+ // The direction of text in popup menu is set the same as the direction of
+ // the input element: textField.
+ m_style.set(new PopupMenuStyle(Color::black, Color::white, font, true,
+ Length(WebCore::Fixed),
+ textField->renderer()->style()->direction()));
+}
+
+WebViewImpl* SuggestionsPopupMenuClient::getWebView() const
+{
+ Frame* frame = m_textField->document()->frame();
+ if (!frame)
+ return 0;
+
+ Page* page = frame->page();
+ if (!page)
+ return 0;
+
+ return static_cast<ChromeClientImpl*>(page->chrome()->client())->webView();
+}
+
+} // namespace WebKit
diff --git a/WebKit/chromium/src/SuggestionsPopupMenuClient.h b/WebKit/chromium/src/SuggestionsPopupMenuClient.h
new file mode 100644
index 0000000..edc4c09
--- /dev/null
+++ b/WebKit/chromium/src/SuggestionsPopupMenuClient.h
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+#include "PopupMenuClient.h"
+
+#ifndef SuggestionsPopupMenuClient_h
+#define SuggestionsPopupMenuClient_h
+
+namespace WebCore {
+class HTMLInputElement;
+class PopupMenuStyle;
+class RenderStyle;
+}
+
+namespace WebKit {
+class WebString;
+class WebViewImpl;
+template <typename T> class WebVector;
+
+// The Suggestions popup menu client, used to display a list of suggestions.
+class SuggestionsPopupMenuClient : public WebCore::PopupMenuClient {
+public:
+ SuggestionsPopupMenuClient();
+ virtual ~SuggestionsPopupMenuClient();
+
+ // Returns the number of suggestions available.
+ virtual unsigned getSuggestionsCount() const = 0;
+
+ // Returns the suggestion at |listIndex|.
+ virtual WebString getSuggestion(unsigned listIndex) const = 0;
+
+ // Removes the suggestion at |listIndex| from the list of suggestions.
+ virtual void removeSuggestionAtIndex(unsigned listIndex) = 0;
+
+ // WebCore::PopupMenuClient methods:
+ virtual void valueChanged(unsigned listIndex, bool fireEvents = true);
+ virtual WebCore::String itemText(unsigned listIndex) const;
+ virtual WebCore::String itemToolTip(unsigned lastIndex) const { return WebCore::String(); }
+ virtual bool itemIsEnabled(unsigned listIndex) const { return true; }
+ virtual WebCore::PopupMenuStyle itemStyle(unsigned listIndex) const;
+ virtual WebCore::PopupMenuStyle menuStyle() const;
+ virtual int clientInsetLeft() const { return 0; }
+ virtual int clientInsetRight() const { return 0; }
+ virtual int clientPaddingLeft() const;
+ virtual int clientPaddingRight() const;
+ virtual int listSize() const { return getSuggestionsCount(); }
+ virtual int selectedIndex() const { return m_selectedIndex; }
+ virtual void popupDidHide();
+ virtual bool itemIsSeparator(unsigned listIndex) const { return false; }
+ virtual bool itemIsLabel(unsigned listIndex) const { return false; }
+ virtual bool itemIsSelected(unsigned listIndex) const { return false; }
+ virtual bool shouldPopOver() const { return false; }
+ virtual bool valueShouldChangeOnHotTrack() const { return false; }
+ virtual void setTextFromItem(unsigned listIndex);
+ virtual WebCore::FontSelector* fontSelector() const;
+ virtual WebCore::HostWindow* hostWindow() const;
+ virtual PassRefPtr<WebCore::Scrollbar> createScrollbar(
+ WebCore::ScrollbarClient* client,
+ WebCore::ScrollbarOrientation orientation,
+ WebCore::ScrollbarControlSize size);
+
+protected:
+ void initialize(WebCore::HTMLInputElement* textField,
+ int defaultSuggestionIndex);
+
+ int getSelectedIndex() const { return m_selectedIndex; }
+ void setSelectedIndex(int index) { m_selectedIndex = index; }
+
+ WebViewImpl* getWebView() const;
+ WebCore::HTMLInputElement* getTextField() const { return m_textField.get(); }
+
+private:
+ WebCore::RenderStyle* textFieldStyle() const;
+
+ RefPtr<WebCore::HTMLInputElement> m_textField;
+ int m_selectedIndex;
+ OwnPtr<WebCore::PopupMenuStyle> m_style;
+};
+
+} // namespace WebKit
+
+#endif
diff --git a/WebKit/chromium/src/ToolsAgent.h b/WebKit/chromium/src/ToolsAgent.h
index fd1fcb7..ab48153 100644
--- a/WebKit/chromium/src/ToolsAgent.h
+++ b/WebKit/chromium/src/ToolsAgent.h
@@ -38,9 +38,6 @@ namespace WebKit {
// Tools agent provides API for enabling / disabling other agents as well as
// API for auxiliary UI functions such as dom elements highlighting.
#define TOOLS_AGENT_STRUCT(METHOD0, METHOD1, METHOD2, METHOD3, METHOD4, METHOD5) \
- /* Request the agent to to run a no-op JavaScript function to trigger v8 execution. */ \
- METHOD0(executeVoidJavaScript) \
- \
/* Dispatches given function on the InspectorController object */ \
METHOD3(dispatchOnInspectorController, int /* call_id */, \
String /* function_name */, String /* json_args */) \
diff --git a/WebKit/chromium/src/WebDatabase.cpp b/WebKit/chromium/src/WebDatabase.cpp
index 2cd36b6..50b9220 100644
--- a/WebKit/chromium/src/WebDatabase.cpp
+++ b/WebKit/chromium/src/WebDatabase.cpp
@@ -32,7 +32,9 @@
#include "WebDatabase.h"
#include "Database.h"
+#include "DatabaseTask.h"
#include "DatabaseThread.h"
+#include "DatabaseTracker.h"
#include "Document.h"
#include "KURL.h"
#include "QuotaTracker.h"
@@ -106,6 +108,22 @@ void WebDatabase::updateDatabaseSize(
originIdentifier, databaseName, databaseSize, spaceAvailable);
}
+void WebDatabase::closeDatabaseImmediately(const WebString& originIdentifier, const WebString& databaseName)
+{
+ HashSet<RefPtr<Database> > databaseHandles;
+ PassRefPtr<SecurityOrigin> originPrp(*WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier));
+ RefPtr<SecurityOrigin> origin = originPrp;
+ DatabaseTracker::tracker().getOpenDatabases(origin.get(), databaseName, &databaseHandles);
+ for (HashSet<RefPtr<Database> >::iterator it = databaseHandles.begin(); it != databaseHandles.end(); ++it) {
+ Database* database = it->get();
+ DatabaseThread* databaseThread = database->scriptExecutionContext()->databaseThread();
+ if (databaseThread && !databaseThread->terminationRequested()) {
+ database->stop();
+ databaseThread->scheduleTask(DatabaseCloseTask::create(database, 0));
+ }
+ }
+}
+
WebDatabase::WebDatabase(const WTF::PassRefPtr<Database>& database)
: m_private(static_cast<WebDatabasePrivate*>(database.releaseRef()))
{
diff --git a/WebKit/chromium/src/WebDevToolsAgentImpl.cpp b/WebKit/chromium/src/WebDevToolsAgentImpl.cpp
index 9d386f3..9ce35b4 100644
--- a/WebKit/chromium/src/WebDevToolsAgentImpl.cpp
+++ b/WebKit/chromium/src/WebDevToolsAgentImpl.cpp
@@ -52,6 +52,7 @@
#include "ScriptState.h"
#include "ScriptValue.h"
#include "V8Binding.h"
+#include "V8InspectorBackend.h"
#include "V8Proxy.h"
#include "V8Utilities.h"
#include "WebDataSource.h"
@@ -87,6 +88,7 @@ using WebCore::ScriptValue;
using WebCore::String;
using WebCore::V8ClassIndex;
using WebCore::V8DOMWrapper;
+using WebCore::V8InspectorBackend;
using WebCore::V8Proxy;
namespace WebKit {
@@ -263,11 +265,6 @@ void WebDevToolsAgentImpl::dispatchOnInjectedScript(int callId, int injectedScri
async);
}
-void WebDevToolsAgentImpl::executeVoidJavaScript()
-{
- m_debuggerAgentImpl->executeVoidJavaScript(m_utilityContext);
-}
-
void WebDevToolsAgentImpl::dispatchMessageFromFrontend(const WebDevToolsMessageData& data)
{
if (ToolsAgentDispatch::dispatch(this, data))
@@ -351,7 +348,7 @@ void WebDevToolsAgentImpl::initDevToolsAgentHost()
v8::Local<v8::Object> WebDevToolsAgentImpl::createInspectorBackendV8Wrapper()
{
V8ClassIndex::V8WrapperType descriptorType = V8ClassIndex::INSPECTORBACKEND;
- v8::Handle<v8::Function> function = V8DOMWrapper::getTemplate(descriptorType)->GetFunction();
+ v8::Handle<v8::Function> function = V8InspectorBackend::GetTemplate()->GetFunction();
if (function.IsEmpty()) {
// Return if allocation failed.
return v8::Local<v8::Object>();
diff --git a/WebKit/chromium/src/WebDevToolsAgentImpl.h b/WebKit/chromium/src/WebDevToolsAgentImpl.h
index 3f5928b..1f81c6d 100644
--- a/WebKit/chromium/src/WebDevToolsAgentImpl.h
+++ b/WebKit/chromium/src/WebDevToolsAgentImpl.h
@@ -70,7 +70,6 @@ public:
// ToolsAgent implementation.
virtual void dispatchOnInspectorController(int callId, const WebCore::String& functionName, const WebCore::String& jsonArgs);
virtual void dispatchOnInjectedScript(int callId, int injectedScriptId, const WebCore::String& functionName, const WebCore::String& jsonArgs, bool async);
- virtual void executeVoidJavaScript();
// WebDevToolsAgentPrivate implementation.
virtual void didClearWindowObject(WebFrameImpl* frame);
diff --git a/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp b/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp
index 0a92319..89fa6e7 100644
--- a/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp
+++ b/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp
@@ -52,7 +52,6 @@
#include "Settings.h"
#include "ToolsAgent.h"
#include "V8Binding.h"
-#include "V8CustomBinding.h"
#include "V8DOMWrapper.h"
#include "V8InspectorFrontendHost.h"
#include "V8Node.h"
@@ -356,7 +355,7 @@ v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsShowContextMenu(const v8::Argum
return v8::Undefined();
v8::Local<v8::Object> eventWrapper = v8::Local<v8::Object>::Cast(args[0]);
- if (V8DOMWrapper::domWrapperType(eventWrapper) != V8ClassIndex::EVENT)
+ if (V8DOMWrapper::domWrapperType(eventWrapper) != V8ClassIndex::MOUSEEVENT)
return v8::Undefined();
Event* event = V8Event::toNative(eventWrapper);
diff --git a/WebKit/chromium/src/WebDragData.cpp b/WebKit/chromium/src/WebDragData.cpp
index 3bd4a02..b18ab1b 100644
--- a/WebKit/chromium/src/WebDragData.cpp
+++ b/WebKit/chromium/src/WebDragData.cpp
@@ -100,6 +100,18 @@ void WebDragData::setDownloadURL(const WebURL& downloadURL)
m_private->downloadURL = downloadURL;
}
+WebString WebDragData::downloadMetadata() const
+{
+ ASSERT(!isNull());
+ return m_private->downloadMetadata;
+}
+
+void WebDragData::setDownloadMetadata(const WebString& downloadMetadata)
+{
+ ensureMutable();
+ m_private->downloadMetadata = downloadMetadata;
+}
+
WebString WebDragData::fileExtension() const
{
ASSERT(!isNull());
diff --git a/WebKit/chromium/src/WebHTTPBody.cpp b/WebKit/chromium/src/WebHTTPBody.cpp
index 335ed5c..3d40869 100644
--- a/WebKit/chromium/src/WebHTTPBody.cpp
+++ b/WebKit/chromium/src/WebHTTPBody.cpp
@@ -32,6 +32,7 @@
#include "WebHTTPBody.h"
#include "FormData.h"
+#include "WebFileInfo.h"
using namespace WebCore;
@@ -78,11 +79,17 @@ bool WebHTTPBody::elementAt(size_t index, Element& result) const
result.type = Element::TypeData;
result.data.assign(element.m_data.data(), element.m_data.size());
result.filePath.reset();
+ result.fileStart = 0;
+ result.fileLength = 0;
+ result.fileInfo.modificationTime = 0.0;
break;
case FormDataElement::encodedFile:
result.type = Element::TypeFile;
result.data.reset();
result.filePath = element.m_filename;
+ result.fileStart = 0; // FIXME: to be set from FormData.
+ result.fileLength = -1; // FIXME: to be set from FormData.
+ result.fileInfo.modificationTime = 0.0; // FIXME: to be set from FormData.
break;
default:
ASSERT_NOT_REACHED();
@@ -106,6 +113,11 @@ void WebHTTPBody::appendFile(const WebString& filePath)
m_private->appendFile(filePath);
}
+void WebHTTPBody::appendFile(const WebString& filePath, long long fileStart, long long fileLength, const WebFileInfo& fileInfo)
+{
+ // FIXME: to be implemented.
+}
+
long long WebHTTPBody::identifier() const
{
ASSERT(!isNull());
diff --git a/WebKit/chromium/src/WebInputElement.cpp b/WebKit/chromium/src/WebInputElement.cpp
index ee799f6..9fd317f 100644
--- a/WebKit/chromium/src/WebInputElement.cpp
+++ b/WebKit/chromium/src/WebInputElement.cpp
@@ -75,7 +75,12 @@ WebString WebInputElement::formControlType() const
{
return constUnwrap<HTMLInputElement>()->formControlType();
}
-
+
+bool WebInputElement::isActivatedSubmit() const
+{
+ return constUnwrap<HTMLInputElement>()->isActivatedSubmit();
+}
+
void WebInputElement::setActivatedSubmit(bool activated)
{
unwrap<HTMLInputElement>()->setActivatedSubmit(activated);
diff --git a/WebKit/chromium/src/WebRuntimeFeatures.cpp b/WebKit/chromium/src/WebRuntimeFeatures.cpp
index 0ef8b9b..ad84764 100644
--- a/WebKit/chromium/src/WebRuntimeFeatures.cpp
+++ b/WebKit/chromium/src/WebRuntimeFeatures.cpp
@@ -123,14 +123,14 @@ bool WebRuntimeFeatures::isSocketsEnabled()
void WebRuntimeFeatures::enableNotifications(bool enable)
{
#if ENABLE(NOTIFICATIONS)
- RuntimeEnabledFeatures::setNotificationsEnabled(enable);
+ RuntimeEnabledFeatures::setWebkitNotificationsEnabled(enable);
#endif
}
bool WebRuntimeFeatures::isNotificationsEnabled()
{
#if ENABLE(NOTIFICATIONS)
- return RuntimeEnabledFeatures::notificationsEnabled();
+ return RuntimeEnabledFeatures::webkitNotificationsEnabled();
#else
return false;
#endif
@@ -171,14 +171,14 @@ bool WebRuntimeFeatures::isGeolocationEnabled()
void WebRuntimeFeatures::enableIndexedDatabase(bool enable)
{
#if ENABLE(INDEXED_DATABASE)
- RuntimeEnabledFeatures::setIndexedDatabaseEnabled(enable);
+ RuntimeEnabledFeatures::setIndexedDBEnabled(enable);
#endif
}
bool WebRuntimeFeatures::isIndexedDatabaseEnabled()
{
#if ENABLE(INDEXED_DATABASE)
- return RuntimeEnabledFeatures::indexedDatabaseEnabled();
+ return RuntimeEnabledFeatures::indexedDBEnabled();
#else
return false;
#endif
diff --git a/WebKit/chromium/src/WebStorageAreaImpl.cpp b/WebKit/chromium/src/WebStorageAreaImpl.cpp
index 92a923a..9a7fd5c 100644
--- a/WebKit/chromium/src/WebStorageAreaImpl.cpp
+++ b/WebKit/chromium/src/WebStorageAreaImpl.cpp
@@ -66,7 +66,7 @@ WebString WebStorageAreaImpl::getItem(const WebString& key)
return m_storageArea->getItem(key);
}
-void WebStorageAreaImpl::setItem(const WebString& key, const WebString& value, const WebURL& url, bool& quotaException, WebString& oldValue)
+void WebStorageAreaImpl::setItem(const WebString& key, const WebString& value, const WebURL& url, Result& result, WebString& oldValue)
{
int exceptionCode = 0;
@@ -75,9 +75,9 @@ void WebStorageAreaImpl::setItem(const WebString& key, const WebString& value, c
if (exceptionCode) {
ASSERT(exceptionCode == WebCore::QUOTA_EXCEEDED_ERR);
- quotaException = true;
+ result = ResultBlockedByQuota;
} else
- quotaException = false;
+ result = ResultOK;
}
void WebStorageAreaImpl::removeItem(const WebString& key, const WebURL& url, WebString& oldValue)
diff --git a/WebKit/chromium/src/WebStorageAreaImpl.h b/WebKit/chromium/src/WebStorageAreaImpl.h
index 7e90531..e9a11c2 100644
--- a/WebKit/chromium/src/WebStorageAreaImpl.h
+++ b/WebKit/chromium/src/WebStorageAreaImpl.h
@@ -45,7 +45,7 @@ public:
virtual unsigned length();
virtual WebString key(unsigned index);
virtual WebString getItem(const WebString& key);
- virtual void setItem(const WebString& key, const WebString& value, const WebURL& url, bool& quotaException, WebString& oldValue);
+ virtual void setItem(const WebString& key, const WebString& value, const WebURL& url, Result& result, WebString& oldValue);
virtual void removeItem(const WebString& key, const WebURL& url, WebString& oldValue);
virtual void clear(const WebURL& url, bool& somethingCleared);
diff --git a/WebKit/chromium/src/WebViewImpl.cpp b/WebKit/chromium/src/WebViewImpl.cpp
index e030d72..ce03523 100644
--- a/WebKit/chromium/src/WebViewImpl.cpp
+++ b/WebKit/chromium/src/WebViewImpl.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * 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
@@ -31,6 +31,7 @@
#include "config.h"
#include "WebViewImpl.h"
+#include "AutoFillPopupMenuClient.h"
#include "AutocompletePopupMenuClient.h"
#include "AXObjectCache.h"
#include "Chrome.h"
@@ -148,16 +149,16 @@ COMPILE_ASSERT_MATCHING_ENUM(DragOperationMove);
COMPILE_ASSERT_MATCHING_ENUM(DragOperationDelete);
COMPILE_ASSERT_MATCHING_ENUM(DragOperationEvery);
-// Note that focusOnShow is false so that the autocomplete popup is shown not
+// Note that focusOnShow is false so that the suggestions popup is shown not
// activated. We need the page to still have focus so the user can keep typing
// while the popup is showing.
-static const PopupContainerSettings autocompletePopupSettings = {
+static const PopupContainerSettings suggestionsPopupSettings = {
false, // focusOnShow
false, // setTextOnIndexChange
false, // acceptOnAbandon
true, // loopSelectionNavigation
true, // restrictWidthOfListBox. Same as other browser (Fx, IE, and safari)
- // For autocomplete, we use the direction of the input field as the direction
+ // For suggestions, we use the direction of the input field as the direction
// of the popup items. The main reason is to keep the display of items in
// drop-down the same as the items in the input field.
PopupContainerSettings::DOMElementDirection,
@@ -239,7 +240,9 @@ WebViewImpl::WebViewImpl(WebViewClient* client)
, m_dropEffect(DropEffectDefault)
, m_operationsAllowed(WebDragOperationNone)
, m_dragOperation(WebDragOperationNone)
- , m_autocompletePopupShowing(false)
+ , m_suggestionsPopupShowing(false)
+ , m_suggestionsPopupClient(0)
+ , m_suggestionsPopup(0)
, m_isTransparent(false)
, m_tabsToLinks(false)
{
@@ -326,7 +329,7 @@ void WebViewImpl::mouseDown(const WebMouseEvent& event)
m_lastMouseDownPoint = WebPoint(event.x, event.y);
// If a text field that has focus is clicked again, we should display the
- // autocomplete popup.
+ // suggestions popup.
RefPtr<Node> clickedNode;
if (event.button == WebMouseEvent::ButtonLeft) {
RefPtr<Node> focusedNode = focusedWebCoreNode();
@@ -348,7 +351,7 @@ void WebViewImpl::mouseDown(const WebMouseEvent& event)
PlatformMouseEventBuilder(mainFrameImpl()->frameView(), event));
if (clickedNode.get() && clickedNode == focusedWebCoreNode()) {
- // Focus has not changed, show the autocomplete popup.
+ // Focus has not changed, show the suggestions popup.
static_cast<EditorClientImpl*>(m_page->editorClient())->
showFormAutofillForNode(clickedNode.get());
}
@@ -468,7 +471,7 @@ bool WebViewImpl::keyEvent(const WebKeyboardEvent& event)
// event.
m_suppressNextKeypressEvent = false;
- // Give autocomplete a chance to consume the key events it is interested in.
+ // Give Autocomplete a chance to consume the key events it is interested in.
if (autocompleteHandleKeyEvent(event))
return true;
@@ -514,7 +517,7 @@ bool WebViewImpl::keyEvent(const WebKeyboardEvent& event)
bool WebViewImpl::autocompleteHandleKeyEvent(const WebKeyboardEvent& event)
{
- if (!m_autocompletePopupShowing
+ if (!m_suggestionsPopupShowing
// Home and End should be left to the text field to process.
|| event.windowsKeyCode == VKEY_HOME
|| event.windowsKeyCode == VKEY_END)
@@ -522,7 +525,7 @@ bool WebViewImpl::autocompleteHandleKeyEvent(const WebKeyboardEvent& event)
// Pressing delete triggers the removal of the selected suggestion from the DB.
if (event.windowsKeyCode == VKEY_DELETE
- && m_autocompletePopup->selectedIndex() != -1) {
+ && m_suggestionsPopup->selectedIndex() != -1) {
Node* node = focusedWebCoreNode();
if (!node || (node->nodeType() != Node::ELEMENT_NODE)) {
ASSERT_NOT_REACHED();
@@ -534,22 +537,22 @@ bool WebViewImpl::autocompleteHandleKeyEvent(const WebKeyboardEvent& event)
return false;
}
- int selectedIndex = m_autocompletePopup->selectedIndex();
+ int selectedIndex = m_suggestionsPopup->selectedIndex();
HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(element);
WebString name = inputElement->name();
WebString value = m_autocompletePopupClient->itemText(selectedIndex);
m_client->removeAutofillSuggestions(name, value);
// Update the entries in the currently showing popup to reflect the
// deletion.
- m_autocompletePopupClient->removeItemAtIndex(selectedIndex);
- refreshAutofillPopup();
+ m_autocompletePopupClient->removeSuggestionAtIndex(selectedIndex);
+ refreshSuggestionsPopup();
return false;
}
- if (!m_autocompletePopup->isInterestedInEventForKey(event.windowsKeyCode))
+ if (!m_suggestionsPopup->isInterestedInEventForKey(event.windowsKeyCode))
return false;
- if (m_autocompletePopup->handleKeyEvent(PlatformKeyboardEventBuilder(event))) {
+ if (m_suggestionsPopup->handleKeyEvent(PlatformKeyboardEventBuilder(event))) {
// We need to ignore the next Char event after this otherwise pressing
// enter when selecting an item in the menu will go to the page.
if (WebInputEvent::RawKeyDown == event.type)
@@ -697,6 +700,7 @@ bool WebViewImpl::keyEventDefault(const WebKeyboardEvent& event)
case WebInputEvent::RawKeyDown:
if (event.modifiers == WebInputEvent::ControlKey) {
switch (event.windowsKeyCode) {
+#if !OS(DARWIN)
case 'A':
focusedFrame()->executeCommand(WebString::fromUTF8("SelectAll"));
return true;
@@ -704,6 +708,7 @@ bool WebViewImpl::keyEventDefault(const WebKeyboardEvent& event)
case 'C':
focusedFrame()->executeCommand(WebString::fromUTF8("Copy"));
return true;
+#endif
// Match FF behavior in the sense that Ctrl+home/end are the only Ctrl
// key combinations which affect scrolling. Safari is buggy in the
// sense that it scrolls the page for all Ctrl+scrolling key
@@ -976,7 +981,7 @@ void WebViewImpl::setFocus(bool enable)
}
m_imeAcceptEvents = true;
} else {
- hideAutoCompletePopup();
+ hideSuggestionsPopup();
// Clear focus on the currently focused frame if any.
if (!m_page.get())
@@ -1182,7 +1187,7 @@ bool WebViewImpl::dispatchBeforeUnloadEvent()
// FIXME: This should really cause a recursive depth-first walk of all
// frames in the tree, calling each frame's onbeforeunload. At the moment,
// we're consistent with Safari 3.1, not IE/FF.
- Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ Frame* frame = m_page->mainFrame();
if (!frame)
return true;
@@ -1558,64 +1563,132 @@ void WebViewImpl::applyAutofillSuggestions(
const WebVector<WebString>& suggestions,
int defaultSuggestionIndex)
{
- if (!m_page.get() || suggestions.isEmpty()) {
- hideAutoCompletePopup();
+ applyAutocompleteSuggestions(node, suggestions, defaultSuggestionIndex);
+}
+
+void WebViewImpl::applyAutoFillSuggestions(
+ const WebNode& node,
+ const WebVector<WebString>& names,
+ const WebVector<WebString>& labels,
+ int defaultSuggestionIndex)
+{
+ ASSERT(names.size() == labels.size());
+ ASSERT(defaultSuggestionIndex < static_cast<int>(names.size()));
+
+ if (names.isEmpty()) {
+ hideSuggestionsPopup();
+ return;
+ }
+
+ RefPtr<Node> focusedNode = focusedWebCoreNode();
+ // If the node for which we queried the AutoFill suggestions is not the
+ // focused node, then we have nothing to do. FIXME: also check the
+ // caret is at the end and that the text has not changed.
+ if (!focusedNode || focusedNode != PassRefPtr<Node>(node)) {
+ hideSuggestionsPopup();
return;
}
+ HTMLInputElement* inputElem =
+ static_cast<HTMLInputElement*>(focusedNode.get());
+
+ // The first time the AutoFill popup is shown we'll create the client and
+ // the popup.
+ if (!m_autoFillPopupClient.get())
+ m_autoFillPopupClient.set(new AutoFillPopupMenuClient);
+
+ m_autoFillPopupClient->initialize(inputElem, names, labels,
+ defaultSuggestionIndex);
+
+ if (m_suggestionsPopupClient != m_autoFillPopupClient.get()) {
+ hideSuggestionsPopup();
+ m_suggestionsPopupClient = m_autoFillPopupClient.get();
+ }
+
+ if (!m_autoFillPopup.get()) {
+ m_autoFillPopup = PopupContainer::create(m_suggestionsPopupClient,
+ suggestionsPopupSettings);
+ }
+
+ if (m_suggestionsPopup != m_autoFillPopup.get())
+ m_suggestionsPopup = m_autoFillPopup.get();
+
+ if (m_suggestionsPopupShowing) {
+ m_autoFillPopupClient->setSuggestions(names, labels);
+ refreshSuggestionsPopup();
+ } else {
+ m_suggestionsPopup->show(focusedNode->getRect(),
+ focusedNode->ownerDocument()->view(), 0);
+ m_suggestionsPopupShowing = true;
+ }
+}
+
+void WebViewImpl::applyAutocompleteSuggestions(
+ const WebNode& node,
+ const WebVector<WebString>& suggestions,
+ int defaultSuggestionIndex)
+{
ASSERT(defaultSuggestionIndex < static_cast<int>(suggestions.size()));
- if (RefPtr<Frame> focused = m_page->focusController()->focusedFrame()) {
- RefPtr<Document> document = focused->document();
- if (!document.get()) {
- hideAutoCompletePopup();
- return;
- }
+ if (!m_page.get() || suggestions.isEmpty()) {
+ hideSuggestionsPopup();
+ return;
+ }
- RefPtr<Node> focusedNode = document->focusedNode();
- // If the node for which we queried the autofill suggestions is not the
- // focused node, then we have nothing to do. FIXME: also check the
- // carret is at the end and that the text has not changed.
- if (!focusedNode.get() || focusedNode != PassRefPtr<Node>(node)) {
- hideAutoCompletePopup();
- return;
- }
+ RefPtr<Node> focusedNode = focusedWebCoreNode();
+ // If the node for which we queried the Autocomplete suggestions is not the
+ // focused node, then we have nothing to do. FIXME: also check the
+ // caret is at the end and that the text has not changed.
+ if (!focusedNode || focusedNode != PassRefPtr<Node>(node)) {
+ hideSuggestionsPopup();
+ return;
+ }
- if (!focusedNode->hasTagName(HTMLNames::inputTag)) {
- ASSERT_NOT_REACHED();
- return;
- }
+ HTMLInputElement* inputElem =
+ static_cast<HTMLInputElement*>(focusedNode.get());
- HTMLInputElement* inputElem =
- static_cast<HTMLInputElement*>(focusedNode.get());
-
- // The first time the autocomplete is shown we'll create the client and the
- // popup.
- if (!m_autocompletePopupClient.get())
- m_autocompletePopupClient.set(new AutocompletePopupMenuClient(this));
- m_autocompletePopupClient->initialize(inputElem,
- suggestions,
- defaultSuggestionIndex);
- if (!m_autocompletePopup.get()) {
- m_autocompletePopup =
- PopupContainer::create(m_autocompletePopupClient.get(),
- autocompletePopupSettings);
- }
+ // The first time the Autocomplete is shown we'll create the client and the
+ // popup.
+ if (!m_autocompletePopupClient.get())
+ m_autocompletePopupClient.set(new AutocompletePopupMenuClient);
- if (m_autocompletePopupShowing) {
- m_autocompletePopupClient->setSuggestions(suggestions);
- refreshAutofillPopup();
- } else {
- m_autocompletePopup->show(focusedNode->getRect(),
- focusedNode->ownerDocument()->view(), 0);
- m_autocompletePopupShowing = true;
- }
+ m_autocompletePopupClient->initialize(inputElem, suggestions,
+ defaultSuggestionIndex);
+
+ if (m_suggestionsPopupClient != m_autocompletePopupClient.get()) {
+ hideSuggestionsPopup();
+ m_suggestionsPopupClient = m_autocompletePopupClient.get();
+ }
+
+ if (!m_autocompletePopup.get()) {
+ m_autocompletePopup = PopupContainer::create(m_suggestionsPopupClient,
+ suggestionsPopupSettings);
+ }
+
+ if (m_suggestionsPopup != m_autocompletePopup.get())
+ m_suggestionsPopup = m_autocompletePopup.get();
+
+ if (m_suggestionsPopupShowing) {
+ m_autocompletePopupClient->setSuggestions(suggestions);
+ refreshSuggestionsPopup();
+ } else {
+ m_suggestionsPopup->show(focusedNode->getRect(),
+ focusedNode->ownerDocument()->view(), 0);
+ m_suggestionsPopupShowing = true;
}
}
void WebViewImpl::hideAutofillPopup()
{
- hideAutoCompletePopup();
+ hideSuggestionsPopup();
+}
+
+void WebViewImpl::hideSuggestionsPopup()
+{
+ if (m_suggestionsPopupShowing) {
+ m_suggestionsPopup->hidePopup();
+ m_suggestionsPopupShowing = false;
+ }
}
void WebViewImpl::performCustomContextMenuAction(unsigned action)
@@ -1778,19 +1851,6 @@ void WebViewImpl::observeNewNavigation()
#endif
}
-void WebViewImpl::hideAutoCompletePopup()
-{
- if (m_autocompletePopupShowing) {
- m_autocompletePopup->hidePopup();
- autoCompletePopupDidHide();
- }
-}
-
-void WebViewImpl::autoCompletePopupDidHide()
-{
- m_autocompletePopupShowing = false;
-}
-
void WebViewImpl::setIgnoreInputEvents(bool newValue)
{
ASSERT(m_ignoreInputEvents != newValue);
@@ -1806,23 +1866,23 @@ NotificationPresenterImpl* WebViewImpl::notificationPresenterImpl()
}
#endif
-void WebViewImpl::refreshAutofillPopup()
+void WebViewImpl::refreshSuggestionsPopup()
{
- ASSERT(m_autocompletePopupShowing);
+ ASSERT(m_suggestionsPopupShowing);
// Hide the popup if it has become empty.
if (!m_autocompletePopupClient->listSize()) {
- hideAutoCompletePopup();
+ hideSuggestionsPopup();
return;
}
- IntRect oldBounds = m_autocompletePopup->boundsRect();
- m_autocompletePopup->refresh();
- IntRect newBounds = m_autocompletePopup->boundsRect();
+ IntRect oldBounds = m_suggestionsPopup->boundsRect();
+ m_suggestionsPopup->refresh();
+ IntRect newBounds = m_suggestionsPopup->boundsRect();
// Let's resize the backing window if necessary.
if (oldBounds != newBounds) {
WebPopupMenuImpl* popupMenu =
- static_cast<WebPopupMenuImpl*>(m_autocompletePopup->client());
+ static_cast<WebPopupMenuImpl*>(m_suggestionsPopup->client());
popupMenu->client()->setWindowRect(newBounds);
}
}
diff --git a/WebKit/chromium/src/WebViewImpl.h b/WebKit/chromium/src/WebViewImpl.h
index e2292f4..286ac43 100644
--- a/WebKit/chromium/src/WebViewImpl.h
+++ b/WebKit/chromium/src/WebViewImpl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * 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
@@ -58,6 +58,7 @@ class KeyboardEvent;
class Page;
class PlatformKeyboardEvent;
class PopupContainer;
+class PopupMenuClient;
class Range;
class RenderTheme;
class Widget;
@@ -65,7 +66,9 @@ class Widget;
namespace WebKit {
class AutocompletePopupMenuClient;
+class AutoFillPopupMenuClient;
class ContextMenuClientImpl;
+class SuggestionsPopupMenuClient;
class WebAccessibilityObject;
class WebDevToolsAgentPrivate;
class WebFrameImpl;
@@ -153,7 +156,17 @@ public:
const WebNode&,
const WebVector<WebString>& suggestions,
int defaultSuggestionIndex);
+ virtual void applyAutoFillSuggestions(
+ const WebNode&,
+ const WebVector<WebString>& names,
+ const WebVector<WebString>& labels,
+ int defaultSuggestionIndex);
+ virtual void applyAutocompleteSuggestions(
+ const WebNode&,
+ const WebVector<WebString>& suggestions,
+ int defaultSuggestionIndex);
virtual void hideAutofillPopup();
+ virtual void hideSuggestionsPopup();
virtual void setScrollbarColors(unsigned inactiveColor,
unsigned activeColor,
unsigned trackColor);
@@ -261,9 +274,10 @@ public:
const WebDragData& dragData,
WebDragOperationsMask dragSourceOperationMask);
- // Hides the autocomplete popup if it is showing.
- void hideAutoCompletePopup();
- void autoCompletePopupDidHide();
+ void suggestionsPopupDidHide()
+ {
+ m_suggestionsPopupShowing = false;
+ }
#if ENABLE(NOTIFICATIONS)
// Returns the provider of desktop notifications.
@@ -295,10 +309,10 @@ private:
// Returns true if the autocomple has consumed the event.
bool autocompleteHandleKeyEvent(const WebKeyboardEvent&);
- // Repaints the autofill popup. Should be called when the suggestions have
- // changed. Note that this should only be called when the autofill popup is
- // showing.
- void refreshAutofillPopup();
+ // Repaints the suggestions popup. Should be called when the suggestions
+ // have changed. Note that this should only be called when the suggestions
+ // popup is showing.
+ void refreshSuggestionsPopup();
// Returns true if the view was scrolled.
bool scrollViewWithKeyboard(int keyCode, int modifiers);
@@ -393,16 +407,29 @@ private:
// current drop target in this WebView (the drop target can accept the drop).
WebDragOperation m_dragOperation;
- // The autocomplete popup. Kept around and reused every-time new suggestions
- // should be shown.
- RefPtr<WebCore::PopupContainer> m_autocompletePopup;
+ // Whether a suggestions popup is currently showing.
+ bool m_suggestionsPopupShowing;
+
+ // A pointer to the current suggestions popup menu client. This can be
+ // either an AutoFillPopupMenuClient or an AutocompletePopupMenuClient. We
+ // do not own this pointer.
+ SuggestionsPopupMenuClient* m_suggestionsPopupClient;
- // Whether the autocomplete popup is currently showing.
- bool m_autocompletePopupShowing;
+ // The AutoFill popup client.
+ OwnPtr<AutoFillPopupMenuClient> m_autoFillPopupClient;
- // The autocomplete client.
+ // The Autocomplete popup client.
OwnPtr<AutocompletePopupMenuClient> m_autocompletePopupClient;
+ // A pointer to the current suggestions popup. We do not own this pointer.
+ WebCore::PopupContainer* m_suggestionsPopup;
+
+ // The AutoFill suggestions popup.
+ RefPtr<WebCore::PopupContainer> m_autoFillPopup;
+
+ // The AutoComplete suggestions popup.
+ RefPtr<WebCore::PopupContainer> m_autocompletePopup;
+
OwnPtr<WebDevToolsAgentPrivate> m_devToolsAgent;
// Whether the webview is rendering transparently.
diff --git a/WebKit/chromium/src/WebWorkerBase.cpp b/WebKit/chromium/src/WebWorkerBase.cpp
index 7fd3749..40019e8 100644
--- a/WebKit/chromium/src/WebWorkerBase.cpp
+++ b/WebKit/chromium/src/WebWorkerBase.cpp
@@ -271,6 +271,8 @@ void WebWorkerBase::workerContextClosedTask(ScriptExecutionContext* context,
{
if (thisPtr->commonClient())
thisPtr->commonClient()->workerContextClosed();
+
+ thisPtr->stopWorkerThread();
}
void WebWorkerBase::workerContextDestroyed()
diff --git a/WebKit/chromium/src/js/DebuggerAgent.js b/WebKit/chromium/src/js/DebuggerAgent.js
new file mode 100644
index 0000000..301620a
--- /dev/null
+++ b/WebKit/chromium/src/js/DebuggerAgent.js
@@ -0,0 +1,1528 @@
+/*
+ * 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 Provides communication interface to remote v8 debugger. See
+ * protocol decription at http://code.google.com/p/v8/wiki/DebuggerProtocol
+ */
+
+/**
+ * FIXME: change field naming style to use trailing underscore.
+ * @constructor
+ */
+devtools.DebuggerAgent = function()
+{
+ RemoteDebuggerAgent.debuggerOutput = this.handleDebuggerOutput_.bind(this);
+ RemoteDebuggerAgent.setContextId = this.setContextId_.bind(this);
+
+ /**
+ * Id of the inspected page global context. It is used for filtering scripts.
+ * @type {number}
+ */
+ this.contextId_ = null;
+
+ /**
+ * Mapping from script id to script info.
+ * @type {Object}
+ */
+ this.parsedScripts_ = null;
+
+ /**
+ * Mapping from the request id to the devtools.BreakpointInfo for the
+ * breakpoints whose v8 ids are not set yet. These breakpoints are waiting for
+ * "setbreakpoint" responses to learn their ids in the v8 debugger.
+ * @see #handleSetBreakpointResponse_
+ * @type {Object}
+ */
+ this.requestNumberToBreakpointInfo_ = null;
+
+ /**
+ * Information on current stack frames.
+ * @type {Array.<devtools.CallFrame>}
+ */
+ this.callFrames_ = [];
+
+ /**
+ * Whether to stop in the debugger on the exceptions.
+ * @type {boolean}
+ */
+ this.pauseOnExceptions_ = false;
+
+ /**
+ * Mapping: request sequence number->callback.
+ * @type {Object}
+ */
+ this.requestSeqToCallback_ = null;
+
+ /**
+ * Whether the scripts panel has been shown and initialilzed.
+ * @type {boolean}
+ */
+ this.scriptsPanelInitialized_ = false;
+
+ /**
+ * Whether the scripts list should be requested next time when context id is
+ * set.
+ * @type {boolean}
+ */
+ this.requestScriptsWhenContextIdSet_ = false;
+
+ /**
+ * Whether the agent is waiting for initial scripts response.
+ * @type {boolean}
+ */
+ this.waitingForInitialScriptsResponse_ = false;
+
+ /**
+ * If backtrace response is received when initial scripts response
+ * is not yet processed the backtrace handling will be postponed until
+ * after the scripts response processing. The handler bound to its arguments
+ * and this agent will be stored in this field then.
+ * @type {?function()}
+ */
+ this.pendingBacktraceResponseHandler_ = null;
+
+ /**
+ * Container of all breakpoints set using resource URL. These breakpoints
+ * survive page reload. Breakpoints set by script id(for scripts that don't
+ * have URLs) are stored in ScriptInfo objects.
+ * @type {Object}
+ */
+ this.urlToBreakpoints_ = {};
+
+
+ /**
+ * Exception message that is shown to user while on exception break.
+ * @type {WebInspector.ConsoleMessage}
+ */
+ this.currentExceptionMessage_ = null;
+};
+
+
+/**
+ * A copy of the scope types from v8/src/mirror-delay.js
+ * @enum {number}
+ */
+devtools.DebuggerAgent.ScopeType = {
+ Global: 0,
+ Local: 1,
+ With: 2,
+ Closure: 3,
+ Catch: 4
+};
+
+
+/**
+ * Resets debugger agent to its initial state.
+ */
+devtools.DebuggerAgent.prototype.reset = function()
+{
+ this.contextId_ = null;
+ // No need to request scripts since they all will be pushed in AfterCompile
+ // events.
+ this.requestScriptsWhenContextIdSet_ = false;
+ this.waitingForInitialScriptsResponse_ = false;
+
+ this.parsedScripts_ = {};
+ this.requestNumberToBreakpointInfo_ = {};
+ this.callFrames_ = [];
+ this.requestSeqToCallback_ = {};
+};
+
+
+/**
+ * Initializes scripts UI. This method is called every time Scripts panel
+ * is shown. It will send request for context id if it's not set yet.
+ */
+devtools.DebuggerAgent.prototype.initUI = function()
+{
+ // Initialize scripts cache when Scripts panel is shown first time.
+ if (this.scriptsPanelInitialized_)
+ return;
+ this.scriptsPanelInitialized_ = true;
+ if (this.contextId_) {
+ // We already have context id. This means that we are here from the
+ // very beginning of the page load cycle and hence will get all scripts
+ // via after-compile events. No need to request scripts for this session.
+ //
+ // There can be a number of scripts from after-compile events that are
+ // pending addition into the UI.
+ for (var scriptId in this.parsedScripts_) {
+ var script = this.parsedScripts_[scriptId];
+ WebInspector.parsedScriptSource(scriptId, script.getUrl(), undefined /* script source */, script.getLineOffset());
+ }
+ return;
+ }
+ this.waitingForInitialScriptsResponse_ = true;
+ // Script list should be requested only when current context id is known.
+ RemoteDebuggerAgent.getContextId();
+ this.requestScriptsWhenContextIdSet_ = true;
+};
+
+
+/**
+ * Asynchronously requests the debugger for the script source.
+ * @param {number} scriptId Id of the script whose source should be resolved.
+ * @param {function(source:?string):void} callback Function that will be called
+ * when the source resolution is completed. "source" parameter will be null
+ * if the resolution fails.
+ */
+devtools.DebuggerAgent.prototype.resolveScriptSource = function(scriptId, callback)
+{
+ var script = this.parsedScripts_[scriptId];
+ if (!script || script.isUnresolved()) {
+ callback(null);
+ return;
+ }
+
+ var cmd = new devtools.DebugCommand("scripts", {
+ "ids": [scriptId],
+ "includeSource": true
+ });
+ devtools.DebuggerAgent.sendCommand_(cmd);
+ // Force v8 execution so that it gets to processing the requested command.
+ RemoteDebuggerAgent.processDebugCommands();
+
+ this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) {
+ if (msg.isSuccess()) {
+ var scriptJson = msg.getBody()[0];
+ if (scriptJson)
+ callback(scriptJson.source);
+ else
+ callback(null);
+ } else
+ callback(null);
+ };
+};
+
+
+/**
+ * Tells the v8 debugger to stop on as soon as possible.
+ */
+devtools.DebuggerAgent.prototype.pauseExecution = function()
+{
+ RemoteDebuggerCommandExecutor.DebuggerPauseScript();
+};
+
+
+/**
+ * @param {number} sourceId Id of the script fot the breakpoint.
+ * @param {number} line Number of the line for the breakpoint.
+ * @param {?string} condition The breakpoint condition.
+ */
+devtools.DebuggerAgent.prototype.addBreakpoint = function(sourceId, line, condition)
+{
+ var script = this.parsedScripts_[sourceId];
+ if (!script)
+ return;
+
+ line = devtools.DebuggerAgent.webkitToV8LineNumber_(line);
+
+ var commandArguments;
+ if (script.getUrl()) {
+ var breakpoints = this.urlToBreakpoints_[script.getUrl()];
+ if (breakpoints && breakpoints[line])
+ return;
+ if (!breakpoints) {
+ breakpoints = {};
+ this.urlToBreakpoints_[script.getUrl()] = breakpoints;
+ }
+
+ var breakpointInfo = new devtools.BreakpointInfo(line);
+ breakpoints[line] = breakpointInfo;
+
+ commandArguments = {
+ "groupId": this.contextId_,
+ "type": "script",
+ "target": script.getUrl(),
+ "line": line,
+ "condition": condition
+ };
+ } else {
+ var breakpointInfo = script.getBreakpointInfo(line);
+ if (breakpointInfo)
+ return;
+
+ breakpointInfo = new devtools.BreakpointInfo(line);
+ script.addBreakpointInfo(breakpointInfo);
+
+ commandArguments = {
+ "groupId": this.contextId_,
+ "type": "scriptId",
+ "target": sourceId,
+ "line": line,
+ "condition": condition
+ };
+ }
+
+ var cmd = new devtools.DebugCommand("setbreakpoint", commandArguments);
+
+ this.requestNumberToBreakpointInfo_[cmd.getSequenceNumber()] = breakpointInfo;
+
+ devtools.DebuggerAgent.sendCommand_(cmd);
+ // Force v8 execution so that it gets to processing the requested command.
+ // It is necessary for being able to change a breakpoint just after it
+ // has been created (since we need an existing breakpoint id for that).
+ RemoteDebuggerAgent.processDebugCommands();
+};
+
+
+/**
+ * @param {number} sourceId Id of the script for the breakpoint.
+ * @param {number} line Number of the line for the breakpoint.
+ */
+devtools.DebuggerAgent.prototype.removeBreakpoint = function(sourceId, line)
+{
+ var script = this.parsedScripts_[sourceId];
+ if (!script)
+ return;
+
+ line = devtools.DebuggerAgent.webkitToV8LineNumber_(line);
+
+ var breakpointInfo;
+ if (script.getUrl()) {
+ var breakpoints = this.urlToBreakpoints_[script.getUrl()];
+ breakpointInfo = breakpoints[line];
+ delete breakpoints[line];
+ } else {
+ breakpointInfo = script.getBreakpointInfo(line);
+ if (breakpointInfo)
+ script.removeBreakpointInfo(breakpointInfo);
+ }
+
+ if (!breakpointInfo)
+ return;
+
+ breakpointInfo.markAsRemoved();
+
+ var id = breakpointInfo.getV8Id();
+
+ // If we don't know id of this breakpoint in the v8 debugger we cannot send
+ // "clearbreakpoint" request. In that case it will be removed in
+ // "setbreakpoint" response handler when we learn the id.
+ if (id !== -1) {
+ this.requestClearBreakpoint_(id);
+ }
+};
+
+
+/**
+ * @param {number} sourceId Id of the script for the breakpoint.
+ * @param {number} line Number of the line for the breakpoint.
+ * @param {?string} condition New breakpoint condition.
+ */
+devtools.DebuggerAgent.prototype.updateBreakpoint = function(sourceId, line, condition)
+{
+ var script = this.parsedScripts_[sourceId];
+ if (!script)
+ return;
+
+ line = devtools.DebuggerAgent.webkitToV8LineNumber_(line);
+
+ var breakpointInfo;
+ if (script.getUrl()) {
+ var breakpoints = this.urlToBreakpoints_[script.getUrl()];
+ breakpointInfo = breakpoints[line];
+ } else
+ breakpointInfo = script.getBreakpointInfo(line);
+
+ var id = breakpointInfo.getV8Id();
+
+ // If we don't know id of this breakpoint in the v8 debugger we cannot send
+ // the "changebreakpoint" request.
+ if (id !== -1) {
+ // TODO(apavlov): make use of the real values for "enabled" and
+ // "ignoreCount" when appropriate.
+ this.requestChangeBreakpoint_(id, true, condition, null);
+ }
+};
+
+
+/**
+ * Tells the v8 debugger to step into the next statement.
+ */
+devtools.DebuggerAgent.prototype.stepIntoStatement = function()
+{
+ this.stepCommand_("in");
+};
+
+
+/**
+ * Tells the v8 debugger to step out of current function.
+ */
+devtools.DebuggerAgent.prototype.stepOutOfFunction = function()
+{
+ this.stepCommand_("out");
+};
+
+
+/**
+ * Tells the v8 debugger to step over the next statement.
+ */
+devtools.DebuggerAgent.prototype.stepOverStatement = function()
+{
+ this.stepCommand_("next");
+};
+
+
+/**
+ * Tells the v8 debugger to continue execution after it has been stopped on a
+ * breakpoint or an exception.
+ */
+devtools.DebuggerAgent.prototype.resumeExecution = function()
+{
+ this.clearExceptionMessage_();
+ var cmd = new devtools.DebugCommand("continue");
+ devtools.DebuggerAgent.sendCommand_(cmd);
+};
+
+
+/**
+ * Creates exception message and schedules it for addition to the resource upon
+ * backtrace availability.
+ * @param {string} url Resource url.
+ * @param {number} line Resource line number.
+ * @param {string} message Exception text.
+ */
+devtools.DebuggerAgent.prototype.createExceptionMessage_ = function(url, line, message)
+{
+ this.currentExceptionMessage_ = new WebInspector.ConsoleMessage(
+ WebInspector.ConsoleMessage.MessageSource.JS,
+ WebInspector.ConsoleMessage.MessageType.Log,
+ WebInspector.ConsoleMessage.MessageLevel.Error,
+ line,
+ url,
+ 0 /* group level */,
+ 1 /* repeat count */,
+ "[Exception] " + message);
+};
+
+
+/**
+ * Shows pending exception message that is created with createExceptionMessage_
+ * earlier.
+ */
+devtools.DebuggerAgent.prototype.showPendingExceptionMessage_ = function()
+{
+ if (!this.currentExceptionMessage_)
+ return;
+ var msg = this.currentExceptionMessage_;
+ var resource = WebInspector.resourceURLMap[msg.url];
+ if (resource) {
+ msg.resource = resource;
+ WebInspector.panels.resources.addMessageToResource(resource, msg);
+ } else
+ this.currentExceptionMessage_ = null;
+};
+
+
+/**
+ * Clears exception message from the resource.
+ */
+devtools.DebuggerAgent.prototype.clearExceptionMessage_ = function()
+{
+ if (this.currentExceptionMessage_) {
+ var messageElement = this.currentExceptionMessage_._resourceMessageLineElement;
+ var bubble = messageElement.parentElement;
+ bubble.removeChild(messageElement);
+ if (!bubble.firstChild) {
+ // Last message in bubble removed.
+ bubble.parentElement.removeChild(bubble);
+ }
+ this.currentExceptionMessage_ = null;
+ }
+};
+
+
+/**
+ * @return {boolean} True iff the debugger will pause execution on the
+ * exceptions.
+ */
+devtools.DebuggerAgent.prototype.pauseOnExceptions = function()
+{
+ return this.pauseOnExceptions_;
+};
+
+
+/**
+ * Tells whether to pause in the debugger on the exceptions or not.
+ * @param {boolean} value True iff execution should be stopped in the debugger
+ * on the exceptions.
+ */
+devtools.DebuggerAgent.prototype.setPauseOnExceptions = function(value)
+{
+ this.pauseOnExceptions_ = value;
+};
+
+
+/**
+ * Sends "evaluate" request to the debugger.
+ * @param {Object} arguments Request arguments map.
+ * @param {function(devtools.DebuggerMessage)} callback Callback to be called
+ * when response is received.
+ */
+devtools.DebuggerAgent.prototype.requestEvaluate = function(arguments, callback)
+{
+ var cmd = new devtools.DebugCommand("evaluate", arguments);
+ devtools.DebuggerAgent.sendCommand_(cmd);
+ this.requestSeqToCallback_[cmd.getSequenceNumber()] = callback;
+};
+
+
+/**
+ * Sends "lookup" request for each unresolved property of the object. When
+ * response is received the properties will be changed with their resolved
+ * values.
+ * @param {Object} object Object whose properties should be resolved.
+ * @param {function(devtools.DebuggerMessage)} Callback to be called when all
+ * children are resolved.
+ * @param {boolean} noIntrinsic Whether intrinsic properties should be included.
+ */
+devtools.DebuggerAgent.prototype.resolveChildren = function(object, callback, noIntrinsic)
+{
+ if ("handle" in object) {
+ var result = [];
+ devtools.DebuggerAgent.formatObjectProperties_(object, result, noIntrinsic);
+ callback(result);
+ } else {
+ this.requestLookup_([object.ref], function(msg) {
+ var result = [];
+ if (msg.isSuccess()) {
+ var handleToObject = msg.getBody();
+ var resolved = handleToObject[object.ref];
+ devtools.DebuggerAgent.formatObjectProperties_(resolved, result, noIntrinsic);
+ callback(result);
+ } else
+ callback([]);
+ });
+ }
+};
+
+
+/**
+ * Sends "scope" request for the scope object to resolve its variables.
+ * @param {Object} scope Scope to be resolved.
+ * @param {function(Array.<WebInspector.ObjectPropertyProxy>)} callback
+ * Callback to be called when all scope variables are resolved.
+ */
+devtools.DebuggerAgent.prototype.resolveScope = function(scope, callback)
+{
+ var cmd = new devtools.DebugCommand("scope", {
+ "frameNumber": scope.frameNumber,
+ "number": scope.index,
+ "compactFormat": true
+ });
+ devtools.DebuggerAgent.sendCommand_(cmd);
+ this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) {
+ var result = [];
+ if (msg.isSuccess()) {
+ var scopeObjectJson = msg.getBody().object;
+ devtools.DebuggerAgent.formatObjectProperties_(scopeObjectJson, result, true /* no intrinsic */);
+ }
+ callback(result);
+ };
+};
+
+
+/**
+ * Sends "scopes" request for the frame object to resolve all variables
+ * available in the frame.
+ * @param {number} callFrameId Id of call frame whose variables need to
+ * be resolved.
+ * @param {function(Object)} callback Callback to be called when all frame
+ * variables are resolved.
+ */
+devtools.DebuggerAgent.prototype.resolveFrameVariables_ = function(callFrameId, callback)
+{
+ var result = {};
+
+ var frame = this.callFrames_[callFrameId];
+ if (!frame) {
+ callback(result);
+ return;
+ }
+
+ var waitingResponses = 0;
+ function scopeResponseHandler(msg) {
+ waitingResponses--;
+
+ if (msg.isSuccess()) {
+ var properties = msg.getBody().object.properties;
+ for (var j = 0; j < properties.length; j++)
+ result[properties[j].name] = true;
+ }
+
+ // When all scopes are resolved invoke the callback.
+ if (waitingResponses === 0)
+ callback(result);
+ };
+
+ for (var i = 0; i < frame.scopeChain.length; i++) {
+ var scope = frame.scopeChain[i].objectId;
+ if (scope.type === devtools.DebuggerAgent.ScopeType.Global) {
+ // Do not resolve global scope since it takes for too long.
+ // TODO(yurys): allow to send only property names in the response.
+ continue;
+ }
+ var cmd = new devtools.DebugCommand("scope", {
+ "frameNumber": scope.frameNumber,
+ "number": scope.index,
+ "compactFormat": true
+ });
+ devtools.DebuggerAgent.sendCommand_(cmd);
+ this.requestSeqToCallback_[cmd.getSequenceNumber()] = scopeResponseHandler;
+ waitingResponses++;
+ }
+};
+
+/**
+ * Evaluates the expressionString to an object in the call frame and reports
+ * all its properties.
+ * @param{string} expressionString Expression whose properties should be
+ * collected.
+ * @param{number} callFrameId The frame id.
+ * @param{function(Object result,bool isException)} reportCompletions Callback
+ * function.
+ */
+devtools.DebuggerAgent.prototype.resolveCompletionsOnFrame = function(expressionString, callFrameId, reportCompletions)
+{
+ if (expressionString) {
+ expressionString = "var obj = " + expressionString +
+ "; var names = {}; for (var n in obj) { names[n] = true; };" +
+ "names;";
+ this.evaluateInCallFrame(
+ callFrameId,
+ expressionString,
+ function(result) {
+ var names = {};
+ if (!result.isException) {
+ var props = result.value.objectId.properties;
+ // Put all object properties into the map.
+ for (var i = 0; i < props.length; i++)
+ names[props[i].name] = true;
+ }
+ reportCompletions(names, result.isException);
+ });
+ } else {
+ this.resolveFrameVariables_(callFrameId,
+ function(result) {
+ reportCompletions(result, false /* isException */);
+ });
+ }
+};
+
+
+/**
+ * @param{number} scriptId
+ * @return {string} Type of the context of the script with specified id.
+ */
+devtools.DebuggerAgent.prototype.getScriptContextType = function(scriptId)
+{
+ return this.parsedScripts_[scriptId].getContextType();
+};
+
+
+/**
+ * Removes specified breakpoint from the v8 debugger.
+ * @param {number} breakpointId Id of the breakpoint in the v8 debugger.
+ */
+devtools.DebuggerAgent.prototype.requestClearBreakpoint_ = function(breakpointId)
+{
+ var cmd = new devtools.DebugCommand("clearbreakpoint", {
+ "breakpoint": breakpointId
+ });
+ devtools.DebuggerAgent.sendCommand_(cmd);
+};
+
+
+/**
+ * Changes breakpoint parameters in the v8 debugger.
+ * @param {number} breakpointId Id of the breakpoint in the v8 debugger.
+ * @param {boolean} enabled Whether to enable the breakpoint.
+ * @param {?string} condition New breakpoint condition.
+ * @param {number} ignoreCount New ignore count for the breakpoint.
+ */
+devtools.DebuggerAgent.prototype.requestChangeBreakpoint_ = function(breakpointId, enabled, condition, ignoreCount)
+{
+ var cmd = new devtools.DebugCommand("changebreakpoint", {
+ "breakpoint": breakpointId,
+ "enabled": enabled,
+ "condition": condition,
+ "ignoreCount": ignoreCount
+ });
+ devtools.DebuggerAgent.sendCommand_(cmd);
+};
+
+
+/**
+ * Sends "backtrace" request to v8.
+ */
+devtools.DebuggerAgent.prototype.requestBacktrace_ = function()
+{
+ var cmd = new devtools.DebugCommand("backtrace", {
+ "compactFormat":true
+ });
+ devtools.DebuggerAgent.sendCommand_(cmd);
+};
+
+
+/**
+ * Sends command to v8 debugger.
+ * @param {devtools.DebugCommand} cmd Command to execute.
+ */
+devtools.DebuggerAgent.sendCommand_ = function(cmd)
+{
+ RemoteDebuggerCommandExecutor.DebuggerCommand(cmd.toJSONProtocol());
+};
+
+
+/**
+ * Tells the v8 debugger to make the next execution step.
+ * @param {string} action "in", "out" or "next" action.
+ */
+devtools.DebuggerAgent.prototype.stepCommand_ = function(action)
+{
+ this.clearExceptionMessage_();
+ var cmd = new devtools.DebugCommand("continue", {
+ "stepaction": action,
+ "stepcount": 1
+ });
+ devtools.DebuggerAgent.sendCommand_(cmd);
+};
+
+
+/**
+ * Sends "lookup" request to v8.
+ * @param {number} handle Handle to the object to lookup.
+ */
+devtools.DebuggerAgent.prototype.requestLookup_ = function(handles, callback)
+{
+ var cmd = new devtools.DebugCommand("lookup", {
+ "compactFormat":true,
+ "handles": handles
+ });
+ devtools.DebuggerAgent.sendCommand_(cmd);
+ this.requestSeqToCallback_[cmd.getSequenceNumber()] = callback;
+};
+
+
+/**
+ * Sets debugger context id for scripts filtering.
+ * @param {number} contextId Id of the inspected page global context.
+ */
+devtools.DebuggerAgent.prototype.setContextId_ = function(contextId)
+{
+ this.contextId_ = contextId;
+
+ // If it's the first time context id is set request scripts list.
+ if (this.requestScriptsWhenContextIdSet_) {
+ this.requestScriptsWhenContextIdSet_ = false;
+ var cmd = new devtools.DebugCommand("scripts", {
+ "includeSource": false
+ });
+ devtools.DebuggerAgent.sendCommand_(cmd);
+ // Force v8 execution so that it gets to processing the requested command.
+ RemoteDebuggerAgent.processDebugCommands();
+
+ var debuggerAgent = this;
+ this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) {
+ // Handle the response iff the context id hasn't changed since the request
+ // was issued. Otherwise if the context id did change all up-to-date
+ // scripts will be pushed in after compile events and there is no need to
+ // handle the response.
+ if (contextId === debuggerAgent.contextId_)
+ debuggerAgent.handleScriptsResponse_(msg);
+
+ // We received initial scripts response so flush the flag and
+ // see if there is an unhandled backtrace response.
+ debuggerAgent.waitingForInitialScriptsResponse_ = false;
+ if (debuggerAgent.pendingBacktraceResponseHandler_) {
+ debuggerAgent.pendingBacktraceResponseHandler_();
+ debuggerAgent.pendingBacktraceResponseHandler_ = null;
+ }
+ };
+ }
+};
+
+
+/**
+ * Handles output sent by v8 debugger. The output is either asynchronous event
+ * or response to a previously sent request. See protocol definitioun for more
+ * details on the output format.
+ * @param {string} output
+ */
+devtools.DebuggerAgent.prototype.handleDebuggerOutput_ = function(output)
+{
+ var msg;
+ try {
+ msg = new devtools.DebuggerMessage(output);
+ } catch(e) {
+ debugPrint("Failed to handle debugger response:\n" + e);
+ throw e;
+ }
+
+ if (msg.getType() === "event") {
+ if (msg.getEvent() === "break")
+ this.handleBreakEvent_(msg);
+ else if (msg.getEvent() === "exception")
+ this.handleExceptionEvent_(msg);
+ else if (msg.getEvent() === "afterCompile")
+ this.handleAfterCompileEvent_(msg);
+ } else if (msg.getType() === "response") {
+ if (msg.getCommand() === "scripts")
+ this.invokeCallbackForResponse_(msg);
+ else if (msg.getCommand() === "setbreakpoint")
+ this.handleSetBreakpointResponse_(msg);
+ else if (msg.getCommand() === "clearbreakpoint")
+ this.handleClearBreakpointResponse_(msg);
+ else if (msg.getCommand() === "backtrace")
+ this.handleBacktraceResponse_(msg);
+ else if (msg.getCommand() === "lookup")
+ this.invokeCallbackForResponse_(msg);
+ else if (msg.getCommand() === "evaluate")
+ this.invokeCallbackForResponse_(msg);
+ else if (msg.getCommand() === "scope")
+ this.invokeCallbackForResponse_(msg);
+ }
+};
+
+
+/**
+ * @param {devtools.DebuggerMessage} msg
+ */
+devtools.DebuggerAgent.prototype.handleBreakEvent_ = function(msg)
+{
+ // Force scrips panel to be shown first.
+ WebInspector.currentPanel = WebInspector.panels.scripts;
+
+ var body = msg.getBody();
+
+ var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine);
+ this.requestBacktrace_();
+};
+
+
+/**
+ * @param {devtools.DebuggerMessage} msg
+ */
+devtools.DebuggerAgent.prototype.handleExceptionEvent_ = function(msg)
+{
+ // Force scrips panel to be shown first.
+ WebInspector.currentPanel = WebInspector.panels.scripts;
+
+ var body = msg.getBody();
+ // No script field in the body means that v8 failed to parse the script. We
+ // resume execution on parser errors automatically.
+ if (this.pauseOnExceptions_ && body.script) {
+ var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine);
+ this.createExceptionMessage_(body.script.name, line, body.exception.text);
+ this.requestBacktrace_();
+ } else
+ this.resumeExecution();
+};
+
+
+/**
+ * @param {devtools.DebuggerMessage} msg
+ */
+devtools.DebuggerAgent.prototype.handleScriptsResponse_ = function(msg)
+{
+ var scripts = msg.getBody();
+ for (var i = 0; i < scripts.length; i++) {
+ var script = scripts[i];
+
+ // Skip scripts from other tabs.
+ if (!this.isScriptFromInspectedContext_(script, msg))
+ continue;
+
+ // We may already have received the info in an afterCompile event.
+ if (script.id in this.parsedScripts_)
+ continue;
+ this.addScriptInfo_(script, msg);
+ }
+};
+
+
+/**
+ * @param {Object} script Json object representing script.
+ * @param {devtools.DebuggerMessage} msg Debugger response.
+ */
+devtools.DebuggerAgent.prototype.isScriptFromInspectedContext_ = function(script, msg)
+{
+ if (!script.context) {
+ // Always ignore scripts from the utility context.
+ return false;
+ }
+ var context = msg.lookup(script.context.ref);
+ var scriptContextId = context.data;
+ if (typeof scriptContextId === "undefined")
+ return false; // Always ignore scripts from the utility context.
+ if (this.contextId_ === null)
+ return true;
+ // Find the id from context data. The context data has the format "type,id".
+ var comma = context.data.indexOf(",");
+ if (comma < 0)
+ return false;
+ return (context.data.substring(comma + 1) == this.contextId_);
+};
+
+
+/**
+ * @param {devtools.DebuggerMessage} msg
+ */
+devtools.DebuggerAgent.prototype.handleSetBreakpointResponse_ = function(msg)
+{
+ var requestSeq = msg.getRequestSeq();
+ var breakpointInfo = this.requestNumberToBreakpointInfo_[requestSeq];
+ if (!breakpointInfo) {
+ // TODO(yurys): handle this case
+ return;
+ }
+ delete this.requestNumberToBreakpointInfo_[requestSeq];
+ if (!msg.isSuccess()) {
+ // TODO(yurys): handle this case
+ return;
+ }
+ var idInV8 = msg.getBody().breakpoint;
+ breakpointInfo.setV8Id(idInV8);
+
+ if (breakpointInfo.isRemoved())
+ this.requestClearBreakpoint_(idInV8);
+};
+
+
+/**
+ * @param {devtools.DebuggerMessage} msg
+ */
+devtools.DebuggerAgent.prototype.handleAfterCompileEvent_ = function(msg)
+{
+ if (!this.contextId_) {
+ // Ignore scripts delta if main request has not been issued yet.
+ return;
+ }
+ var script = msg.getBody().script;
+
+ // Ignore scripts from other tabs.
+ if (!this.isScriptFromInspectedContext_(script, msg))
+ return;
+ this.addScriptInfo_(script, msg);
+};
+
+
+/**
+ * Adds the script info to the local cache. This method assumes that the script
+ * is not in the cache yet.
+ * @param {Object} script Script json object from the debugger message.
+ * @param {devtools.DebuggerMessage} msg Debugger message containing the script
+ * data.
+ */
+devtools.DebuggerAgent.prototype.addScriptInfo_ = function(script, msg)
+{
+ var context = msg.lookup(script.context.ref);
+ var contextType;
+ // Find the type from context data. The context data has the format
+ // "type,id".
+ var comma = context.data.indexOf(",");
+ if (comma < 0)
+ return
+ contextType = context.data.substring(0, comma);
+ this.parsedScripts_[script.id] = new devtools.ScriptInfo(script.id, script.name, script.lineOffset, contextType);
+ if (this.scriptsPanelInitialized_) {
+ // Only report script as parsed after scripts panel has been shown.
+ WebInspector.parsedScriptSource(script.id, script.name, script.source, script.lineOffset);
+ }
+};
+
+
+/**
+ * @param {devtools.DebuggerMessage} msg
+ */
+devtools.DebuggerAgent.prototype.handleClearBreakpointResponse_ = function(msg)
+{
+ // Do nothing.
+};
+
+
+/**
+ * Handles response to "backtrace" command.
+ * @param {devtools.DebuggerMessage} msg
+ */
+devtools.DebuggerAgent.prototype.handleBacktraceResponse_ = function(msg)
+{
+ if (this.waitingForInitialScriptsResponse_)
+ this.pendingBacktraceResponseHandler_ = this.doHandleBacktraceResponse_.bind(this, msg);
+ else
+ this.doHandleBacktraceResponse_(msg);
+};
+
+
+/**
+ * @param {devtools.DebuggerMessage} msg
+ */
+devtools.DebuggerAgent.prototype.doHandleBacktraceResponse_ = function(msg)
+{
+ var frames = msg.getBody().frames;
+ this.callFrames_ = [];
+ for (var i = 0; i < frames.length; ++i)
+ this.callFrames_.push(this.formatCallFrame_(frames[i]));
+ WebInspector.pausedScript(this.callFrames_);
+ this.showPendingExceptionMessage_();
+ InspectorFrontendHost.activateWindow();
+};
+
+
+/**
+ * Evaluates code on given callframe.
+ */
+devtools.DebuggerAgent.prototype.evaluateInCallFrame = function(callFrameId, code, callback)
+{
+ var callFrame = this.callFrames_[callFrameId];
+ callFrame.evaluate_(code, callback);
+};
+
+
+/**
+ * Handles response to a command by invoking its callback (if any).
+ * @param {devtools.DebuggerMessage} msg
+ * @return {boolean} Whether a callback for the given message was found and
+ * excuted.
+ */
+devtools.DebuggerAgent.prototype.invokeCallbackForResponse_ = function(msg)
+{
+ var callback = this.requestSeqToCallback_[msg.getRequestSeq()];
+ if (!callback) {
+ // It may happend if reset was called.
+ return false;
+ }
+ delete this.requestSeqToCallback_[msg.getRequestSeq()];
+ callback(msg);
+ return true;
+};
+
+
+/**
+ * @param {Object} stackFrame Frame json object from "backtrace" response.
+ * @return {!devtools.CallFrame} Object containing information related to the
+ * call frame in the format expected by ScriptsPanel and its panes.
+ */
+devtools.DebuggerAgent.prototype.formatCallFrame_ = function(stackFrame)
+{
+ var func = stackFrame.func;
+ var sourceId = func.scriptId;
+
+ // Add service script if it does not exist.
+ var existingScript = this.parsedScripts_[sourceId];
+ if (!existingScript) {
+ this.parsedScripts_[sourceId] = new devtools.ScriptInfo(sourceId, null /* name */, 0 /* line */, "unknown" /* type */, true /* unresolved */);
+ WebInspector.parsedScriptSource(sourceId, null, null, 0);
+ }
+
+ var funcName = func.name || func.inferredName || "(anonymous function)";
+ var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(stackFrame.line);
+
+ // Add basic scope chain info with scope variables.
+ var scopeChain = [];
+ var ScopeType = devtools.DebuggerAgent.ScopeType;
+ for (var i = 0; i < stackFrame.scopes.length; i++) {
+ var scope = stackFrame.scopes[i];
+ scope.frameNumber = stackFrame.index;
+ var scopeObjectProxy = new WebInspector.ObjectProxy(0, scope, [], 0, "", true);
+ scopeObjectProxy.isScope = true;
+ switch(scope.type) {
+ case ScopeType.Global:
+ scopeObjectProxy.isDocument = true;
+ break;
+ case ScopeType.Local:
+ scopeObjectProxy.isLocal = true;
+ scopeObjectProxy.thisObject = devtools.DebuggerAgent.formatObjectProxy_(stackFrame.receiver);
+ break;
+ case ScopeType.With:
+ // Catch scope is treated as a regular with scope by WebKit so we
+ // also treat it this way.
+ case ScopeType.Catch:
+ scopeObjectProxy.isWithBlock = true;
+ break;
+ case ScopeType.Closure:
+ scopeObjectProxy.isClosure = true;
+ break;
+ }
+ scopeChain.push(scopeObjectProxy);
+ }
+ return new devtools.CallFrame(stackFrame.index, "function", funcName, sourceId, line, scopeChain);
+};
+
+
+/**
+ * Collects properties for an object from the debugger response.
+ * @param {Object} object An object from the debugger protocol response.
+ * @param {Array.<WebInspector.ObjectPropertyProxy>} result An array to put the
+ * properties into.
+ * @param {boolean} noIntrinsic Whether intrinsic properties should be
+ * included.
+ */
+devtools.DebuggerAgent.formatObjectProperties_ = function(object, result, noIntrinsic)
+{
+ devtools.DebuggerAgent.propertiesToProxies_(object.properties, result);
+ if (noIntrinsic)
+ return;
+
+ result.push(new WebInspector.ObjectPropertyProxy("__proto__", devtools.DebuggerAgent.formatObjectProxy_(object.protoObject)));
+ result.push(new WebInspector.ObjectPropertyProxy("constructor", devtools.DebuggerAgent.formatObjectProxy_(object.constructorFunction)));
+ // Don't add 'prototype' property since it is one of the regualar properties.
+};
+
+
+/**
+ * For each property in "properties" creates its proxy representative.
+ * @param {Array.<Object>} properties Receiver properties or locals array from
+ * "backtrace" response.
+ * @param {Array.<WebInspector.ObjectPropertyProxy>} Results holder.
+ */
+devtools.DebuggerAgent.propertiesToProxies_ = function(properties, result)
+{
+ var map = {};
+ for (var i = 0; i < properties.length; ++i) {
+ var property = properties[i];
+ var name = String(property.name);
+ if (name in map)
+ continue;
+ map[name] = true;
+ var value = devtools.DebuggerAgent.formatObjectProxy_(property.value);
+ var propertyProxy = new WebInspector.ObjectPropertyProxy(name, value);
+ result.push(propertyProxy);
+ }
+};
+
+
+/**
+ * @param {Object} v An object reference from the debugger response.
+ * @return {*} The value representation expected by ScriptsPanel.
+ */
+devtools.DebuggerAgent.formatObjectProxy_ = function(v)
+{
+ var description;
+ var hasChildren = false;
+ if (v.type === "object") {
+ description = v.className;
+ hasChildren = true;
+ } else if (v.type === "function") {
+ if (v.source)
+ description = v.source;
+ else
+ description = "function " + v.name + "()";
+ hasChildren = true;
+ } else if (v.type === "undefined")
+ description = "undefined";
+ else if (v.type === "null")
+ description = "null";
+ else if (typeof v.value !== "undefined") {
+ // Check for undefined and null types before checking the value, otherwise
+ // null/undefined may have blank value.
+ description = v.value;
+ } else
+ description = "<unresolved ref: " + v.ref + ", type: " + v.type + ">";
+
+ var proxy = new WebInspector.ObjectProxy(0, v, [], 0, description, hasChildren);
+ proxy.type = v.type;
+ proxy.isV8Ref = true;
+ return proxy;
+};
+
+
+/**
+ * Converts line number from Web Inspector UI(1-based) to v8(0-based).
+ * @param {number} line Resource line number in Web Inspector UI.
+ * @return {number} The line number in v8.
+ */
+devtools.DebuggerAgent.webkitToV8LineNumber_ = function(line)
+{
+ return line - 1;
+};
+
+
+/**
+ * Converts line number from v8(0-based) to Web Inspector UI(1-based).
+ * @param {number} line Resource line number in v8.
+ * @return {number} The line number in Web Inspector.
+ */
+devtools.DebuggerAgent.v8ToWwebkitLineNumber_ = function(line)
+{
+ return line + 1;
+};
+
+
+/**
+ * @param {number} scriptId Id of the script.
+ * @param {?string} url Script resource URL if any.
+ * @param {number} lineOffset First line 0-based offset in the containing
+ * document.
+ * @param {string} contextType Type of the script's context:
+ * "page" - regular script from html page
+ * "injected" - extension content script
+ * @param {bool} opt_isUnresolved If true, script will not be resolved.
+ * @constructor
+ */
+devtools.ScriptInfo = function(scriptId, url, lineOffset, contextType, opt_isUnresolved)
+{
+ this.scriptId_ = scriptId;
+ this.lineOffset_ = lineOffset;
+ this.contextType_ = contextType;
+ this.url_ = url;
+ this.isUnresolved_ = opt_isUnresolved;
+
+ this.lineToBreakpointInfo_ = {};
+};
+
+
+/**
+ * @return {number}
+ */
+devtools.ScriptInfo.prototype.getLineOffset = function()
+{
+ return this.lineOffset_;
+};
+
+
+/**
+ * @return {string}
+ */
+devtools.ScriptInfo.prototype.getContextType = function()
+{
+ return this.contextType_;
+};
+
+
+/**
+ * @return {?string}
+ */
+devtools.ScriptInfo.prototype.getUrl = function()
+{
+ return this.url_;
+};
+
+
+/**
+ * @return {?bool}
+ */
+devtools.ScriptInfo.prototype.isUnresolved = function()
+{
+ return this.isUnresolved_;
+};
+
+
+/**
+ * @param {number} line 0-based line number in the script.
+ * @return {?devtools.BreakpointInfo} Information on a breakpoint at the
+ * specified line in the script or undefined if there is no breakpoint at
+ * that line.
+ */
+devtools.ScriptInfo.prototype.getBreakpointInfo = function(line)
+{
+ return this.lineToBreakpointInfo_[line];
+};
+
+
+/**
+ * Adds breakpoint info to the script.
+ * @param {devtools.BreakpointInfo} breakpoint
+ */
+devtools.ScriptInfo.prototype.addBreakpointInfo = function(breakpoint)
+{
+ this.lineToBreakpointInfo_[breakpoint.getLine()] = breakpoint;
+};
+
+
+/**
+ * @param {devtools.BreakpointInfo} breakpoint Breakpoint info to be removed.
+ */
+devtools.ScriptInfo.prototype.removeBreakpointInfo = function(breakpoint)
+{
+ var line = breakpoint.getLine();
+ delete this.lineToBreakpointInfo_[line];
+};
+
+
+
+/**
+ * @param {number} line Breakpoint 0-based line number in the containing script.
+ * @constructor
+ */
+devtools.BreakpointInfo = function(line)
+{
+ this.line_ = line;
+ this.v8id_ = -1;
+ this.removed_ = false;
+};
+
+
+/**
+ * @return {number}
+ */
+devtools.BreakpointInfo.prototype.getLine = function(n)
+{
+ return this.line_;
+};
+
+
+/**
+ * @return {number} Unique identifier of this breakpoint in the v8 debugger.
+ */
+devtools.BreakpointInfo.prototype.getV8Id = function(n)
+{
+ return this.v8id_;
+};
+
+
+/**
+ * Sets id of this breakpoint in the v8 debugger.
+ * @param {number} id
+ */
+devtools.BreakpointInfo.prototype.setV8Id = function(id)
+{
+ this.v8id_ = id;
+};
+
+
+/**
+ * Marks this breakpoint as removed from the front-end.
+ */
+devtools.BreakpointInfo.prototype.markAsRemoved = function()
+{
+ this.removed_ = true;
+};
+
+
+/**
+ * @return {boolean} Whether this breakpoint has been removed from the
+ * front-end.
+ */
+devtools.BreakpointInfo.prototype.isRemoved = function()
+{
+ return this.removed_;
+};
+
+
+/**
+ * Call stack frame data.
+ * @param {string} id CallFrame id.
+ * @param {string} type CallFrame type.
+ * @param {string} functionName CallFrame type.
+ * @param {string} sourceID Source id.
+ * @param {number} line Source line.
+ * @param {Array.<Object>} scopeChain Array of scoped objects.
+ * @construnctor
+ */
+devtools.CallFrame = function(id, type, functionName, sourceID, line, scopeChain)
+{
+ this.id = id;
+ this.type = type;
+ this.functionName = functionName;
+ this.sourceID = sourceID;
+ this.line = line;
+ this.scopeChain = scopeChain;
+};
+
+
+/**
+ * This method issues asynchronous evaluate request, reports result to the
+ * callback.
+ * @param {string} expression An expression to be evaluated in the context of
+ * this call frame.
+ * @param {function(Object):undefined} callback Callback to report result to.
+ */
+devtools.CallFrame.prototype.evaluate_ = function(expression, callback)
+{
+ devtools.tools.getDebuggerAgent().requestEvaluate({
+ "expression": expression,
+ "frame": this.id,
+ "global": false,
+ "disable_break": false,
+ "compactFormat": true
+ },
+ function(response) {
+ var result = {};
+ if (response.isSuccess())
+ result.value = devtools.DebuggerAgent.formatObjectProxy_(response.getBody());
+ else {
+ result.value = response.getMessage();
+ result.isException = true;
+ }
+ callback(result);
+ });
+};
+
+
+/**
+ * JSON based commands sent to v8 debugger.
+ * @param {string} command Name of the command to execute.
+ * @param {Object} opt_arguments Command-specific arguments map.
+ * @constructor
+ */
+devtools.DebugCommand = function(command, opt_arguments)
+{
+ this.command_ = command;
+ this.type_ = "request";
+ this.seq_ = ++devtools.DebugCommand.nextSeq_;
+ if (opt_arguments)
+ this.arguments_ = opt_arguments;
+};
+
+
+/**
+ * Next unique number to be used as debugger request sequence number.
+ * @type {number}
+ */
+devtools.DebugCommand.nextSeq_ = 1;
+
+
+/**
+ * @return {number}
+ */
+devtools.DebugCommand.prototype.getSequenceNumber = function()
+{
+ return this.seq_;
+};
+
+
+/**
+ * @return {string}
+ */
+devtools.DebugCommand.prototype.toJSONProtocol = function()
+{
+ var json = {
+ "seq": this.seq_,
+ "type": this.type_,
+ "command": this.command_
+ }
+ if (this.arguments_)
+ json.arguments = this.arguments_;
+ return JSON.stringify(json);
+};
+
+
+/**
+ * JSON messages sent from v8 debugger. See protocol definition for more
+ * details: http://code.google.com/p/v8/wiki/DebuggerProtocol
+ * @param {string} msg Raw protocol packet as JSON string.
+ * @constructor
+ */
+devtools.DebuggerMessage = function(msg)
+{
+ this.packet_ = JSON.parse(msg);
+ this.refs_ = [];
+ if (this.packet_.refs) {
+ for (var i = 0; i < this.packet_.refs.length; i++)
+ this.refs_[this.packet_.refs[i].handle] = this.packet_.refs[i];
+ }
+};
+
+
+/**
+ * @return {string} The packet type.
+ */
+devtools.DebuggerMessage.prototype.getType = function()
+{
+ return this.packet_.type;
+};
+
+
+/**
+ * @return {?string} The packet event if the message is an event.
+ */
+devtools.DebuggerMessage.prototype.getEvent = function()
+{
+ return this.packet_.event;
+};
+
+
+/**
+ * @return {?string} The packet command if the message is a response to a
+ * command.
+ */
+devtools.DebuggerMessage.prototype.getCommand = function()
+{
+ return this.packet_.command;
+};
+
+
+/**
+ * @return {number} The packet request sequence.
+ */
+devtools.DebuggerMessage.prototype.getRequestSeq = function()
+{
+ return this.packet_.request_seq;
+};
+
+
+/**
+ * @return {number} Whether the v8 is running after processing the request.
+ */
+devtools.DebuggerMessage.prototype.isRunning = function()
+{
+ return this.packet_.running ? true : false;
+};
+
+
+/**
+ * @return {boolean} Whether the request succeeded.
+ */
+devtools.DebuggerMessage.prototype.isSuccess = function()
+{
+ return this.packet_.success ? true : false;
+};
+
+
+/**
+ * @return {string}
+ */
+devtools.DebuggerMessage.prototype.getMessage = function()
+{
+ return this.packet_.message;
+};
+
+
+/**
+ * @return {Object} Parsed message body json.
+ */
+devtools.DebuggerMessage.prototype.getBody = function()
+{
+ return this.packet_.body;
+};
+
+
+/**
+ * @param {number} handle Object handle.
+ * @return {?Object} Returns the object with the handle if it was sent in this
+ * message(some objects referenced by handles may be missing in the message).
+ */
+devtools.DebuggerMessage.prototype.lookup = function(handle)
+{
+ return this.refs_[handle];
+};
diff --git a/WebKit/chromium/src/js/DevTools.js b/WebKit/chromium/src/js/DevTools.js
new file mode 100644
index 0000000..dcb181b
--- /dev/null
+++ b/WebKit/chromium/src/js/DevTools.js
@@ -0,0 +1,504 @@
+/*
+ * 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.
+ */
+
+/**
+ * Dispatches raw message from the host.
+ * @param {string} remoteName
+ * @prama {string} methodName
+ * @param {string} param1, param2, param3 Arguments to dispatch.
+ */
+devtools$$dispatch = function(remoteName, methodName, param1, param2, param3)
+{
+ remoteName = "Remote" + remoteName.substring(0, remoteName.length - 8);
+ var agent = window[remoteName];
+ if (!agent) {
+ debugPrint("No remote agent '" + remoteName + "' found.");
+ return;
+ }
+ var method = agent[methodName];
+ if (!method) {
+ debugPrint("No method '" + remoteName + "." + methodName + "' found.");
+ return;
+ }
+ method.call(this, param1, param2, param3);
+};
+
+
+devtools.ToolsAgent = function()
+{
+ RemoteToolsAgent.didDispatchOn = WebInspector.Callback.processCallback;
+ RemoteToolsAgent.frameNavigate = this.frameNavigate_.bind(this);
+ RemoteToolsAgent.dispatchOnClient = this.dispatchOnClient_.bind(this);
+ this.debuggerAgent_ = new devtools.DebuggerAgent();
+ this.profilerAgent_ = new devtools.ProfilerAgent();
+};
+
+
+/**
+ * Resets tools agent to its initial state.
+ */
+devtools.ToolsAgent.prototype.reset = function()
+{
+ this.debuggerAgent_.reset();
+};
+
+
+/**
+ * @param {string} script Script exression to be evaluated in the context of the
+ * inspected page.
+ * @param {function(Object|string, boolean):undefined} opt_callback Function to
+ * call with the result.
+ */
+devtools.ToolsAgent.prototype.evaluateJavaScript = function(script, opt_callback)
+{
+ InspectorBackend.evaluate(script, opt_callback || function() {});
+};
+
+
+/**
+ * @return {devtools.DebuggerAgent} Debugger agent instance.
+ */
+devtools.ToolsAgent.prototype.getDebuggerAgent = function()
+{
+ return this.debuggerAgent_;
+};
+
+
+/**
+ * @return {devtools.ProfilerAgent} Profiler agent instance.
+ */
+devtools.ToolsAgent.prototype.getProfilerAgent = function()
+{
+ return this.profilerAgent_;
+};
+
+
+/**
+ * @param {string} url Url frame navigated to.
+ * @see tools_agent.h
+ * @private
+ */
+devtools.ToolsAgent.prototype.frameNavigate_ = function(url)
+{
+ this.reset();
+ // Do not reset Profiles panel.
+ var profiles = null;
+ if ("profiles" in WebInspector.panels) {
+ profiles = WebInspector.panels["profiles"];
+ delete WebInspector.panels["profiles"];
+ }
+ WebInspector.reset();
+ if (profiles !== null)
+ WebInspector.panels["profiles"] = profiles;
+};
+
+
+/**
+ * @param {string} message Serialized call to be dispatched on WebInspector.
+ * @private
+ */
+devtools.ToolsAgent.prototype.dispatchOnClient_ = function(message)
+{
+ var args = JSON.parse(message);
+ var methodName = args[0];
+ var parameters = args.slice(1);
+ WebInspector[methodName].apply(WebInspector, parameters);
+};
+
+
+/**
+ * Evaluates js expression.
+ * @param {string} expr
+ */
+devtools.ToolsAgent.prototype.evaluate = function(expr)
+{
+ RemoteToolsAgent.evaluate(expr);
+};
+
+
+/**
+ * Enables / disables resources panel in the ui.
+ * @param {boolean} enabled New panel status.
+ */
+WebInspector.setResourcesPanelEnabled = function(enabled)
+{
+ InspectorBackend._resourceTrackingEnabled = enabled;
+ WebInspector.panels.resources.reset();
+};
+
+
+/**
+ * Prints string to the inspector console or shows alert if the console doesn't
+ * exist.
+ * @param {string} text
+ */
+function debugPrint(text) {
+ var console = WebInspector.console;
+ if (console) {
+ console.addMessage(new WebInspector.ConsoleMessage(
+ WebInspector.ConsoleMessage.MessageSource.JS,
+ WebInspector.ConsoleMessage.MessageType.Log,
+ WebInspector.ConsoleMessage.MessageLevel.Log,
+ 1, "chrome://devtools/<internal>", undefined, -1, text));
+ } else
+ alert(text);
+}
+
+
+/**
+ * Global instance of the tools agent.
+ * @type {devtools.ToolsAgent}
+ */
+devtools.tools = null;
+
+
+var context = {}; // Used by WebCore's inspector routines.
+
+///////////////////////////////////////////////////////////////////////////////
+// Here and below are overrides to existing WebInspector methods only.
+// TODO(pfeldman): Patch WebCore and upstream changes.
+var oldLoaded = WebInspector.loaded;
+WebInspector.loaded = function()
+{
+ devtools.tools = new devtools.ToolsAgent();
+ devtools.tools.reset();
+
+ Preferences.ignoreWhitespace = false;
+ Preferences.samplingCPUProfiler = true;
+ Preferences.heapProfilerPresent = true;
+ oldLoaded.call(this);
+
+ InspectorFrontendHost.loaded();
+};
+
+
+(function()
+{
+
+ /**
+ * Handles an F3 keydown event to focus the Inspector search box.
+ * @param {KeyboardEvent} event Event to optionally handle
+ * @return {boolean} whether the event has been handled
+ */
+ function handleF3Keydown(event) {
+ if (event.keyIdentifier === "F3" && !event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey) {
+ var searchField = document.getElementById("search");
+ searchField.focus();
+ searchField.select();
+ event.preventDefault();
+ return true;
+ }
+ return false;
+ }
+
+
+ var oldKeyDown = WebInspector.documentKeyDown;
+ /**
+ * This override allows to intercept keydown events we want to handle in a
+ * custom way. Some nested documents (iframes) delegate keydown handling to
+ * WebInspector.documentKeyDown (e.g. SourceFrame).
+ * @param {KeyboardEvent} event
+ * @override
+ */
+ WebInspector.documentKeyDown = function(event) {
+ var isHandled = handleF3Keydown(event);
+ if (!isHandled) {
+ // Mute refresh action.
+ if (event.keyIdentifier === "F5")
+ event.preventDefault();
+ else if (event.keyIdentifier === "U+0052" /* "R" */ && (event.ctrlKey || event.metaKey))
+ event.preventDefault();
+ else
+ oldKeyDown.call(this, event);
+ }
+ };
+})();
+
+
+/**
+ * This override is necessary for adding script source asynchronously.
+ * @override
+ */
+WebInspector.ScriptView.prototype.setupSourceFrameIfNeeded = function()
+{
+ if (!this._frameNeedsSetup)
+ return;
+
+ this.attach();
+
+ if (this.script.source)
+ this.didResolveScriptSource_();
+ else {
+ var self = this;
+ devtools.tools.getDebuggerAgent().resolveScriptSource(
+ this.script.sourceID,
+ function(source) {
+ self.script.source = source || WebInspector.UIString("<source is not available>");
+ self.didResolveScriptSource_();
+ });
+ }
+};
+
+
+/**
+ * Performs source frame setup when script source is aready resolved.
+ */
+WebInspector.ScriptView.prototype.didResolveScriptSource_ = function()
+{
+ this.sourceFrame.setContent("text/javascript", this.script.source);
+ this._sourceFrameSetup = true;
+ delete this._frameNeedsSetup;
+};
+
+
+/**
+ * @param {string} type Type of the the property value("object" or "function").
+ * @param {string} className Class name of the property value.
+ * @constructor
+ */
+WebInspector.UnresolvedPropertyValue = function(type, className)
+{
+ this.type = type;
+ this.className = className;
+};
+
+
+(function()
+{
+ var oldShow = WebInspector.ScriptsPanel.prototype.show;
+ WebInspector.ScriptsPanel.prototype.show = function()
+ {
+ devtools.tools.getDebuggerAgent().initUI();
+ this.enableToggleButton.visible = false;
+ oldShow.call(this);
+ };
+})();
+
+
+(function InterceptProfilesPanelEvents()
+{
+ var oldShow = WebInspector.ProfilesPanel.prototype.show;
+ WebInspector.ProfilesPanel.prototype.show = function()
+ {
+ devtools.tools.getProfilerAgent().initializeProfiling();
+ 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));
+};
+
+
+// There is no clear way of setting frame title yet. So sniffing main resource
+// load.
+(function OverrideUpdateResource() {
+ var originalUpdateResource = WebInspector.updateResource;
+ WebInspector.updateResource = function(identifier, payload)
+ {
+ originalUpdateResource.call(this, identifier, payload);
+ var resource = this.resources[identifier];
+ if (resource && resource.mainResource && resource.finished)
+ document.title = WebInspector.UIString("Developer Tools - %s", resource.url);
+ };
+})();
+
+
+// Highlight extension content scripts in the scripts list.
+(function () {
+ var original = WebInspector.ScriptsPanel.prototype._addScriptToFilesMenu;
+ WebInspector.ScriptsPanel.prototype._addScriptToFilesMenu = function(script)
+ {
+ var result = original.apply(this, arguments);
+ var debuggerAgent = devtools.tools.getDebuggerAgent();
+ var type = debuggerAgent.getScriptContextType(script.sourceID);
+ var option = script.filesSelectOption;
+ if (type === "injected" && option)
+ option.addStyleClass("injected");
+ return result;
+ };
+})();
+
+
+/** 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);
+ };
+})();
+
+
+(function () {
+var orig = InjectedScriptAccess.prototype.getProperties;
+InjectedScriptAccess.prototype.getProperties = function(objectProxy, ignoreHasOwnProperty, abbreviate, callback)
+{
+ if (objectProxy.isScope)
+ devtools.tools.getDebuggerAgent().resolveScope(objectProxy.objectId, callback);
+ else if (objectProxy.isV8Ref)
+ devtools.tools.getDebuggerAgent().resolveChildren(objectProxy.objectId, callback, false);
+ else
+ orig.apply(this, arguments);
+};
+})();
+
+
+(function()
+{
+InjectedScriptAccess.prototype.evaluateInCallFrame = function(callFrameId, code, objectGroup, callback)
+{
+ //TODO(pfeldman): remove once 49084 is rolled.
+ if (!callback)
+ callback = objectGroup;
+ devtools.tools.getDebuggerAgent().evaluateInCallFrame(callFrameId, code, callback);
+};
+})();
+
+
+WebInspector.resourceTrackingWasEnabled = function()
+{
+ InspectorBackend._resourceTrackingEnabled = true;
+ this.panels.resources.resourceTrackingWasEnabled();
+};
+
+WebInspector.resourceTrackingWasDisabled = function()
+{
+ InspectorBackend._resourceTrackingEnabled = false;
+ this.panels.resources.resourceTrackingWasDisabled();
+};
+
+(function()
+{
+var orig = WebInspector.ConsoleMessage.prototype.setMessageBody;
+WebInspector.ConsoleMessage.prototype.setMessageBody = function(args)
+{
+ for (var i = 0; i < args.length; ++i) {
+ if (typeof args[i] === "string")
+ args[i] = WebInspector.ObjectProxy.wrapPrimitiveValue(args[i]);
+ }
+ orig.call(this, args);
+};
+})();
+
+
+(function()
+{
+var orig = InjectedScriptAccess.prototype.getCompletions;
+InjectedScriptAccess.prototype.getCompletions = function(expressionString, includeInspectorCommandLineAPI, callFrameId, reportCompletions)
+{
+ if (typeof callFrameId === "number")
+ devtools.tools.getDebuggerAgent().resolveCompletionsOnFrame(expressionString, callFrameId, reportCompletions);
+ else
+ return orig.apply(this, arguments);
+};
+})();
+
+
+(function()
+{
+WebInspector.ElementsPanel.prototype._nodeSearchButtonClicked = function( event)
+{
+ InspectorBackend.toggleNodeSearch();
+ this.nodeSearchButton.toggled = !this.nodeSearchButton.toggled;
+};
+})();
+
+
+// We need to have a place for postponed tasks
+// which should be executed when all the messages between agent and frontend
+// are processed.
+
+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);
+};
+
+(function()
+{
+var originalAddToFrame = InspectorFrontendHost.addResourceSourceToFrame;
+InspectorFrontendHost.addResourceSourceToFrame = function(identifier, element)
+{
+ var resource = WebInspector.resources[identifier];
+ if (!resource)
+ return;
+ originalAddToFrame.call(this, identifier, resource.mimeType, element);
+};
+})();
+
+WebInspector.pausedScript = function(callFrames)
+{
+ this.panels.scripts.debuggerPaused(callFrames);
+};
diff --git a/WebKit/chromium/src/js/DevToolsHostStub.js b/WebKit/chromium/src/js/DevToolsHostStub.js
new file mode 100644
index 0000000..8b2f46b
--- /dev/null
+++ b/WebKit/chromium/src/js/DevToolsHostStub.js
@@ -0,0 +1,309 @@
+/*
+ * 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 These stubs emulate backend functionality and allows
+ * DevTools frontend to function as a standalone web app.
+ */
+
+if (!window["RemoteDebuggerAgent"]) {
+
+/**
+ * FIXME: change field naming style to use trailing underscore.
+ * @constructor
+ */
+RemoteDebuggerAgentStub = function()
+{
+};
+
+
+RemoteDebuggerAgentStub.prototype.getContextId = function()
+{
+ RemoteDebuggerAgent.setContextId(3);
+};
+
+
+RemoteDebuggerAgentStub.prototype.processDebugCommands = function()
+{
+};
+
+
+/**
+ * @constructor
+ */
+RemoteProfilerAgentStub = function()
+{
+};
+
+
+RemoteProfilerAgentStub.prototype.getActiveProfilerModules = function()
+{
+ ProfilerStubHelper.GetInstance().getActiveProfilerModules();
+};
+
+
+RemoteProfilerAgentStub.prototype.getLogLines = function(pos)
+{
+ ProfilerStubHelper.GetInstance().getLogLines(pos);
+};
+
+
+/**
+ * @constructor
+ */
+RemoteToolsAgentStub = function()
+{
+};
+
+
+RemoteToolsAgentStub.prototype.dispatchOnInjectedScript = function()
+{
+};
+
+
+RemoteToolsAgentStub.prototype.dispatchOnInspectorController = function()
+{
+};
+
+
+/**
+ * @constructor
+ */
+ProfilerStubHelper = function()
+{
+ this.activeProfilerModules_ = devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE;
+ this.heapProfSample_ = 0;
+ this.log_ = '';
+};
+
+
+ProfilerStubHelper.GetInstance = function()
+{
+ if (!ProfilerStubHelper.instance_)
+ ProfilerStubHelper.instance_ = new ProfilerStubHelper();
+ return ProfilerStubHelper.instance_;
+};
+
+
+ProfilerStubHelper.prototype.StopProfiling = function(modules)
+{
+ this.activeProfilerModules_ &= ~modules;
+};
+
+
+ProfilerStubHelper.prototype.StartProfiling = function(modules)
+{
+ var profModules = devtools.ProfilerAgent.ProfilerModules;
+ if (modules & profModules.PROFILER_MODULE_HEAP_SNAPSHOT) {
+ if (modules & profModules.PROFILER_MODULE_HEAP_STATS) {
+ this.log_ +=
+ 'heap-sample-begin,"Heap","allocated",' +
+ (new Date()).getTime() + '\n' +
+ 'heap-sample-stats,"Heap","allocated",10000,1000\n';
+ this.log_ +=
+ 'heap-sample-item,STRING_TYPE,100,1000\n' +
+ 'heap-sample-item,CODE_TYPE,10,200\n' +
+ 'heap-sample-item,MAP_TYPE,20,350\n';
+ this.log_ += ProfilerStubHelper.HeapSamples[this.heapProfSample_++];
+ this.heapProfSample_ %= ProfilerStubHelper.HeapSamples.length;
+ this.log_ += 'heap-sample-end,"Heap","allocated"\n';
+ }
+ } else {
+ if (modules & profModules.PROFILER_MODULE_CPU)
+ this.log_ += ProfilerStubHelper.ProfilerLogBuffer;
+ this.activeProfilerModules_ |= modules;
+ }
+};
+
+
+ProfilerStubHelper.prototype.getActiveProfilerModules = function()
+{
+ var self = this;
+ setTimeout(function() {
+ RemoteProfilerAgent.didGetActiveProfilerModules(self.activeProfilerModules_);
+ }, 100);
+};
+
+
+ProfilerStubHelper.prototype.getLogLines = function(pos)
+{
+ var profModules = devtools.ProfilerAgent.ProfilerModules;
+ var logLines = this.log_.substr(pos);
+ setTimeout(function() {
+ RemoteProfilerAgent.didGetLogLines(pos + logLines.length, logLines);
+ }, 100);
+};
+
+
+ProfilerStubHelper.ProfilerLogBuffer =
+ 'profiler,begin,1\n' +
+ 'profiler,resume\n' +
+ 'code-creation,LazyCompile,0x1000,256,"test1 http://aaa.js:1"\n' +
+ 'code-creation,LazyCompile,0x2000,256,"test2 http://bbb.js:2"\n' +
+ 'code-creation,LazyCompile,0x3000,256,"test3 http://ccc.js:3"\n' +
+ 'tick,0x1010,0x0,3\n' +
+ 'tick,0x2020,0x0,3,0x1010\n' +
+ 'tick,0x2020,0x0,3,0x1010\n' +
+ 'tick,0x3010,0x0,3,0x2020, 0x1010\n' +
+ 'tick,0x2020,0x0,3,0x1010\n' +
+ 'tick,0x2030,0x0,3,0x2020, 0x1010\n' +
+ 'tick,0x2020,0x0,3,0x1010\n' +
+ 'tick,0x1010,0x0,3\n' +
+ 'profiler,pause\n';
+
+
+ProfilerStubHelper.HeapSamples = [
+ 'heap-js-cons-item,foo,1,100\n' +
+ 'heap-js-cons-item,bar,20,2000\n' +
+ 'heap-js-cons-item,Object,5,100\n' +
+ 'heap-js-ret-item,foo,bar;3\n' +
+ 'heap-js-ret-item,bar,foo;5\n' +
+ 'heap-js-ret-item,Object:0x1234,(roots);1\n',
+
+ 'heap-js-cons-item,foo,2000,200000\n' +
+ 'heap-js-cons-item,bar,10,1000\n' +
+ 'heap-js-cons-item,Object,6,120\n' +
+ 'heap-js-ret-item,foo,bar;7,Object:0x1234;10\n' +
+ 'heap-js-ret-item,bar,foo;10,Object:0x1234;10\n' +
+ 'heap-js-ret-item,Object:0x1234,(roots);1\n',
+
+ 'heap-js-cons-item,foo,15,1500\n' +
+ 'heap-js-cons-item,bar,15,1500\n' +
+ 'heap-js-cons-item,Object,5,100\n' +
+ 'heap-js-cons-item,Array,3,1000\n' +
+ 'heap-js-ret-item,foo,bar;3,Array:0x5678;1\n' +
+ 'heap-js-ret-item,bar,foo;5,Object:0x1234;8,Object:0x5678;2\n' +
+ 'heap-js-ret-item,Object:0x1234,(roots);1,Object:0x5678;2\n' +
+ 'heap-js-ret-item,Object:0x5678,(global property);3,Object:0x1234;5\n' +
+ 'heap-js-ret-item,Array:0x5678,(global property);3,Array:0x5678;2\n',
+
+ 'heap-js-cons-item,bar,20,2000\n' +
+ 'heap-js-cons-item,Object,6,120\n' +
+ 'heap-js-ret-item,bar,foo;5,Object:0x1234;1,Object:0x1235;3\n' +
+ 'heap-js-ret-item,Object:0x1234,(global property);3\n' +
+ 'heap-js-ret-item,Object:0x1235,(global property);5\n',
+
+ 'heap-js-cons-item,foo,15,1500\n' +
+ 'heap-js-cons-item,bar,15,1500\n' +
+ 'heap-js-cons-item,Array,10,1000\n' +
+ 'heap-js-ret-item,foo,bar;1,Array:0x5678;1\n' +
+ 'heap-js-ret-item,bar,foo;5\n' +
+ 'heap-js-ret-item,Array:0x5678,(roots);3\n',
+
+ 'heap-js-cons-item,bar,20,2000\n' +
+ 'heap-js-cons-item,baz,15,1500\n' +
+ 'heap-js-ret-item,bar,baz;3\n' +
+ 'heap-js-ret-item,baz,bar;3\n'
+];
+
+
+/**
+ * @constructor
+ */
+RemoteDebuggerCommandExecutorStub = function()
+{
+};
+
+
+RemoteDebuggerCommandExecutorStub.prototype.DebuggerCommand = function(cmd)
+{
+ if ('{"seq":2,"type":"request","command":"scripts","arguments":{"includeSource":false}}' === cmd) {
+ var response1 =
+ '{"seq":5,"request_seq":2,"type":"response","command":"scripts","' +
+ 'success":true,"body":[{"handle":61,"type":"script","name":"' +
+ 'http://www/~test/t.js","id":59,"lineOffset":0,"columnOffset":0,' +
+ '"lineCount":1,"sourceStart":"function fib(n) {","sourceLength":300,' +
+ '"scriptType":2,"compilationType":0,"context":{"ref":60}}],"refs":[{' +
+ '"handle":60,"type":"context","data":"page,3"}],"running":false}';
+ this.sendResponse_(response1);
+ } else if ('{"seq":3,"type":"request","command":"scripts","arguments":{"ids":[59],"includeSource":true}}' === cmd) {
+ this.sendResponse_(
+ '{"seq":8,"request_seq":3,"type":"response","command":"scripts",' +
+ '"success":true,"body":[{"handle":1,"type":"script","name":' +
+ '"http://www/~test/t.js","id":59,"lineOffset":0,"columnOffset":0,' +
+ '"lineCount":1,"source":"function fib(n) {return n+1;}",' +
+ '"sourceLength":244,"scriptType":2,"compilationType":0,"context":{' +
+ '"ref":0}}],"refs":[{"handle":0,"type":"context","data":"page,3}],"' +
+ '"running":false}');
+ } else if (cmd.indexOf('"command":"profile"') !== -1) {
+ var cmdObj = JSON.parse(cmd);
+ if (cmdObj.arguments.command === "resume")
+ ProfilerStubHelper.GetInstance().StartProfiling(parseInt(cmdObj.arguments.modules));
+ else if (cmdObj.arguments.command === "pause")
+ ProfilerStubHelper.GetInstance().StopProfiling(parseInt(cmdObj.arguments.modules));
+ else
+ debugPrint("Unexpected profile command: " + cmdObj.arguments.command);
+ } else
+ debugPrint("Unexpected command: " + cmd);
+};
+
+
+RemoteDebuggerCommandExecutorStub.prototype.DebuggerPauseScript = function()
+{
+};
+
+
+RemoteDebuggerCommandExecutorStub.prototype.sendResponse_ = function(response)
+{
+ setTimeout(function() {
+ RemoteDebuggerAgent.debuggerOutput(response);
+ }, 0);
+};
+
+
+DevToolsHostStub = function()
+{
+ this.isStub = true;
+};
+DevToolsHostStub.prototype.__proto__ = WebInspector.InspectorFrontendHostStub.prototype;
+
+
+DevToolsHostStub.prototype.reset = function()
+{
+};
+
+
+DevToolsHostStub.prototype.setting = function()
+{
+};
+
+
+DevToolsHostStub.prototype.setSetting = function()
+{
+};
+
+
+window["RemoteDebuggerAgent"] = new RemoteDebuggerAgentStub();
+window["RemoteDebuggerCommandExecutor"] = new RemoteDebuggerCommandExecutorStub();
+window["RemoteProfilerAgent"] = new RemoteProfilerAgentStub();
+window["RemoteToolsAgent"] = new RemoteToolsAgentStub();
+InspectorFrontendHost = new DevToolsHostStub();
+
+}
diff --git a/WebKit/chromium/src/js/HeapProfilerPanel.js b/WebKit/chromium/src/js/HeapProfilerPanel.js
new file mode 100644
index 0000000..abbf580
--- /dev/null
+++ b/WebKit/chromium/src/js/HeapProfilerPanel.js
@@ -0,0 +1,966 @@
+/*
+ * 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 Heap profiler panel implementation.
+ */
+
+WebInspector.ProfilesPanel.prototype.addSnapshot = function(snapshot) {
+ snapshot.title = WebInspector.UIString("Snapshot %d", snapshot.number);
+ snapshot.typeId = WebInspector.HeapSnapshotProfileType.TypeId;
+
+ var snapshots = WebInspector.HeapSnapshotProfileType.snapshots;
+ snapshots.push(snapshot);
+
+ snapshot.listIndex = snapshots.length - 1;
+
+ if (WebInspector.CPUProfile)
+ this.addProfileHeader(WebInspector.HeapSnapshotProfileType.TypeId, snapshot);
+ else
+ this.addProfileHeader(snapshot);
+
+ this.dispatchEventToListeners("snapshot added");
+}
+
+
+WebInspector.HeapSnapshotView = function(parent, profile)
+{
+ WebInspector.View.call(this);
+
+ this.element.addStyleClass("heap-snapshot-view");
+
+ this.parent = parent;
+ this.parent.addEventListener("snapshot added", this._updateBaseOptions, this);
+
+ this.showCountAsPercent = false;
+ this.showSizeAsPercent = false;
+ this.showCountDeltaAsPercent = false;
+ this.showSizeDeltaAsPercent = false;
+
+ this.categories = {
+ code: new WebInspector.ResourceCategory("code", WebInspector.UIString("Code"), "rgb(255,121,0)"),
+ data: new WebInspector.ResourceCategory("data", WebInspector.UIString("Objects"), "rgb(47,102,236)")
+ };
+
+ var summaryContainer = document.createElement("div");
+ summaryContainer.id = "heap-snapshot-summary-container";
+
+ this.countsSummaryBar = new WebInspector.SummaryBar(this.categories);
+ this.countsSummaryBar.element.className = "heap-snapshot-summary";
+ this.countsSummaryBar.calculator = new WebInspector.HeapSummaryCountCalculator();
+ var countsLabel = document.createElement("div");
+ countsLabel.className = "heap-snapshot-summary-label";
+ countsLabel.textContent = WebInspector.UIString("Count");
+ this.countsSummaryBar.element.appendChild(countsLabel);
+ summaryContainer.appendChild(this.countsSummaryBar.element);
+
+ this.sizesSummaryBar = new WebInspector.SummaryBar(this.categories);
+ this.sizesSummaryBar.element.className = "heap-snapshot-summary";
+ this.sizesSummaryBar.calculator = new WebInspector.HeapSummarySizeCalculator();
+ var sizesLabel = document.createElement("label");
+ sizesLabel.className = "heap-snapshot-summary-label";
+ sizesLabel.textContent = WebInspector.UIString("Size");
+ this.sizesSummaryBar.element.appendChild(sizesLabel);
+ summaryContainer.appendChild(this.sizesSummaryBar.element);
+
+ this.element.appendChild(summaryContainer);
+
+ var columns = { "cons": { title: WebInspector.UIString("Constructor"), disclosure: true, sortable: true },
+ "count": { title: WebInspector.UIString("Count"), width: "54px", sortable: true },
+ "size": { title: WebInspector.UIString("Size"), width: "72px", sort: "descending", sortable: true },
+ "countDelta": { title: WebInspector.UIString("\xb1 Count"), width: "72px", sortable: true },
+ "sizeDelta": { title: WebInspector.UIString("\xb1 Size"), width: "72px", sortable: true } };
+
+ this.dataGrid = new WebInspector.DataGrid(columns);
+ this.dataGrid.addEventListener("sorting changed", this._sortData, this);
+ this.dataGrid.element.addEventListener("mousedown", this._mouseDownInDataGrid.bind(this), true);
+ this.element.appendChild(this.dataGrid.element);
+
+ this.profile = profile;
+
+ this.baseSelectElement = document.createElement("select");
+ this.baseSelectElement.className = "status-bar-item";
+ this.baseSelectElement.addEventListener("change", this._changeBase.bind(this), false);
+ this._updateBaseOptions();
+ if (this.profile.listIndex > 0)
+ this.baseSelectElement.selectedIndex = this.profile.listIndex - 1;
+ else
+ this.baseSelectElement.selectedIndex = this.profile.listIndex;
+ this._resetDataGridList();
+
+ this.percentButton = new WebInspector.StatusBarButton("", "percent-time-status-bar-item status-bar-item");
+ this.percentButton.addEventListener("click", this._percentClicked.bind(this), false);
+
+ this.refresh();
+
+ this._updatePercentButton();
+};
+
+WebInspector.HeapSnapshotView.prototype = {
+
+ get statusBarItems()
+ {
+ return [this.baseSelectElement, this.percentButton.element];
+ },
+
+ get profile()
+ {
+ return this._profile;
+ },
+
+ set profile(profile)
+ {
+ this._profile = profile;
+ },
+
+ show: function(parentElement)
+ {
+ WebInspector.View.prototype.show.call(this, parentElement);
+ this.dataGrid.updateWidths();
+ },
+
+ hide: function()
+ {
+ WebInspector.View.prototype.hide.call(this);
+ this._currentSearchResultIndex = -1;
+ },
+
+ resize: function()
+ {
+ if (this.dataGrid)
+ this.dataGrid.updateWidths();
+ },
+
+ refresh: function()
+ {
+ this.dataGrid.removeChildren();
+
+ var children = this.snapshotDataGridList.children;
+ var count = children.length;
+ for (var index = 0; index < count; ++index)
+ this.dataGrid.appendChild(children[index]);
+
+ this._updateSummaryGraph();
+ },
+
+ refreshShowAsPercents: function()
+ {
+ this._updatePercentButton();
+ this.refreshVisibleData();
+ },
+
+ _deleteSearchMatchedFlags: function(node)
+ {
+ delete node._searchMatchedConsColumn;
+ delete node._searchMatchedCountColumn;
+ delete node._searchMatchedSizeColumn;
+ delete node._searchMatchedCountDeltaColumn;
+ delete node._searchMatchedSizeDeltaColumn;
+ },
+
+ searchCanceled: function()
+ {
+ if (this._searchResults) {
+ for (var i = 0; i < this._searchResults.length; ++i) {
+ var profileNode = this._searchResults[i].profileNode;
+ this._deleteSearchMatchedFlags(profileNode);
+ profileNode.refresh();
+ }
+ }
+
+ delete this._searchFinishedCallback;
+ this._currentSearchResultIndex = -1;
+ this._searchResults = [];
+ },
+
+ performSearch: function(query, finishedCallback)
+ {
+ // Call searchCanceled since it will reset everything we need before doing a new search.
+ this.searchCanceled();
+
+ query = query.trimWhitespace();
+
+ if (!query.length)
+ return;
+
+ this._searchFinishedCallback = finishedCallback;
+
+ var helper = WebInspector.HeapSnapshotView.SearchHelper;
+
+ var operationAndNumber = helper.parseOperationAndNumber(query);
+ var operation = operationAndNumber[0];
+ var queryNumber = operationAndNumber[1];
+
+ var percentUnits = helper.percents.test(query);
+ var megaBytesUnits = helper.megaBytes.test(query);
+ var kiloBytesUnits = helper.kiloBytes.test(query);
+ var bytesUnits = helper.bytes.test(query);
+
+ var queryNumberBytes = (megaBytesUnits ? (queryNumber * 1024 * 1024) : (kiloBytesUnits ? (queryNumber * 1024) : queryNumber));
+
+ function matchesQuery(heapSnapshotDataGridNode)
+ {
+ WebInspector.HeapSnapshotView.prototype._deleteSearchMatchedFlags(heapSnapshotDataGridNode);
+
+ if (percentUnits) {
+ heapSnapshotDataGridNode._searchMatchedCountColumn = operation(heapSnapshotDataGridNode.countPercent, queryNumber);
+ heapSnapshotDataGridNode._searchMatchedSizeColumn = operation(heapSnapshotDataGridNode.sizePercent, queryNumber);
+ heapSnapshotDataGridNode._searchMatchedCountDeltaColumn = operation(heapSnapshotDataGridNode.countDeltaPercent, queryNumber);
+ heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn = operation(heapSnapshotDataGridNode.sizeDeltaPercent, queryNumber);
+ } else if (megaBytesUnits || kiloBytesUnits || bytesUnits) {
+ heapSnapshotDataGridNode._searchMatchedSizeColumn = operation(heapSnapshotDataGridNode.size, queryNumberBytes);
+ heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn = operation(heapSnapshotDataGridNode.sizeDelta, queryNumberBytes);
+ } else {
+ heapSnapshotDataGridNode._searchMatchedCountColumn = operation(heapSnapshotDataGridNode.count, queryNumber);
+ heapSnapshotDataGridNode._searchMatchedCountDeltaColumn = operation(heapSnapshotDataGridNode.countDelta, queryNumber);
+ }
+
+ if (heapSnapshotDataGridNode.constructorName.hasSubstring(query, true))
+ heapSnapshotDataGridNode._searchMatchedConsColumn = true;
+
+ if (heapSnapshotDataGridNode._searchMatchedConsColumn ||
+ heapSnapshotDataGridNode._searchMatchedCountColumn ||
+ heapSnapshotDataGridNode._searchMatchedSizeColumn ||
+ heapSnapshotDataGridNode._searchMatchedCountDeltaColumn ||
+ heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn) {
+ heapSnapshotDataGridNode.refresh();
+ return true;
+ }
+
+ return false;
+ }
+
+ var current = this.snapshotDataGridList.children[0];
+ var depth = 0;
+ var info = {};
+
+ // The second and subsequent levels of heap snapshot nodes represent retainers,
+ // so recursive expansion will be infinite, since a graph is being traversed.
+ // So default to a recursion cap of 2 levels.
+ var maxDepth = 2;
+
+ while (current) {
+ if (matchesQuery(current))
+ this._searchResults.push({ profileNode: current });
+ current = current.traverseNextNode(false, null, (depth >= maxDepth), info);
+ depth += info.depthChange;
+ }
+
+ finishedCallback(this, this._searchResults.length);
+ },
+
+ jumpToFirstSearchResult: WebInspector.CPUProfileView.prototype.jumpToFirstSearchResult,
+ jumpToLastSearchResult: WebInspector.CPUProfileView.prototype.jumpToLastSearchResult,
+ jumpToNextSearchResult: WebInspector.CPUProfileView.prototype.jumpToNextSearchResult,
+ jumpToPreviousSearchResult: WebInspector.CPUProfileView.prototype.jumpToPreviousSearchResult,
+ showingFirstSearchResult: WebInspector.CPUProfileView.prototype.showingFirstSearchResult,
+ showingLastSearchResult: WebInspector.CPUProfileView.prototype.showingLastSearchResult,
+ _jumpToSearchResult: WebInspector.CPUProfileView.prototype._jumpToSearchResult,
+
+ refreshVisibleData: function()
+ {
+ var child = this.dataGrid.children[0];
+ while (child) {
+ child.refresh();
+ child = child.traverseNextNode(false, null, true);
+ }
+ this._updateSummaryGraph();
+ },
+
+ _changeBase: function() {
+ if (this.baseSnapshot === WebInspector.HeapSnapshotProfileType.snapshots[this.baseSelectElement.selectedIndex])
+ return;
+
+ this._resetDataGridList();
+ this.refresh();
+
+ if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
+ return;
+
+ // The current search needs to be performed again. First negate out previous match
+ // count by calling the search finished callback with a negative number of matches.
+ // Then perform the search again with the same query and callback.
+ this._searchFinishedCallback(this, -this._searchResults.length);
+ this.performSearch(this.currentQuery, this._searchFinishedCallback);
+ },
+
+ _createSnapshotDataGridList: function()
+ {
+ if (this._snapshotDataGridList)
+ delete this._snapshotDataGridList;
+
+ this._snapshotDataGridList = new WebInspector.HeapSnapshotDataGridList(this, this.baseSnapshot.entries, this.profile.entries);
+ return this._snapshotDataGridList;
+ },
+
+ _mouseDownInDataGrid: function(event)
+ {
+ if (event.detail < 2)
+ return;
+
+ var cell = event.target.enclosingNodeOrSelfWithNodeName("td");
+ if (!cell || (!cell.hasStyleClass("count-column") && !cell.hasStyleClass("size-column") && !cell.hasStyleClass("countDelta-column") && !cell.hasStyleClass("sizeDelta-column")))
+ return;
+
+ if (cell.hasStyleClass("count-column"))
+ this.showCountAsPercent = !this.showCountAsPercent;
+ else if (cell.hasStyleClass("size-column"))
+ this.showSizeAsPercent = !this.showSizeAsPercent;
+ else if (cell.hasStyleClass("countDelta-column"))
+ this.showCountDeltaAsPercent = !this.showCountDeltaAsPercent;
+ else if (cell.hasStyleClass("sizeDelta-column"))
+ this.showSizeDeltaAsPercent = !this.showSizeDeltaAsPercent;
+
+ this.refreshShowAsPercents();
+
+ event.preventDefault();
+ event.stopPropagation();
+ },
+
+ get _isShowingAsPercent()
+ {
+ return this.showCountAsPercent && this.showSizeAsPercent && this.showCountDeltaAsPercent && this.showSizeDeltaAsPercent;
+ },
+
+ _percentClicked: function(event)
+ {
+ var currentState = this._isShowingAsPercent;
+ this.showCountAsPercent = !currentState;
+ this.showSizeAsPercent = !currentState;
+ this.showCountDeltaAsPercent = !currentState;
+ this.showSizeDeltaAsPercent = !currentState;
+ this.refreshShowAsPercents();
+ },
+
+ _resetDataGridList: function()
+ {
+ this.baseSnapshot = WebInspector.HeapSnapshotProfileType.snapshots[this.baseSelectElement.selectedIndex];
+ var lastComparator = WebInspector.HeapSnapshotDataGridList.propertyComparator("size", false);
+ if (this.snapshotDataGridList)
+ lastComparator = this.snapshotDataGridList.lastComparator;
+ this.snapshotDataGridList = this._createSnapshotDataGridList();
+ this.snapshotDataGridList.sort(lastComparator, true);
+ },
+
+ _sortData: function()
+ {
+ var sortAscending = this.dataGrid.sortOrder === "ascending";
+ var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier;
+ var sortProperty = {
+ "cons": ["constructorName", null],
+ "count": ["count", null],
+ "size": ["size", "count"],
+ "countDelta": this.showCountDeltaAsPercent ? ["countDeltaPercent", null] : ["countDelta", null],
+ "sizeDelta": this.showSizeDeltaAsPercent ? ["sizeDeltaPercent", "countDeltaPercent"] : ["sizeDelta", "sizeDeltaPercent"]
+ }[sortColumnIdentifier];
+
+ this.snapshotDataGridList.sort(WebInspector.HeapSnapshotDataGridList.propertyComparator(sortProperty[0], sortProperty[1], sortAscending));
+
+ this.refresh();
+ },
+
+ _updateBaseOptions: function()
+ {
+ var list = WebInspector.HeapSnapshotProfileType.snapshots;
+ // We're assuming that snapshots can only be added.
+ if (this.baseSelectElement.length === list.length)
+ return;
+
+ for (var i = this.baseSelectElement.length, n = list.length; i < n; ++i) {
+ var baseOption = document.createElement("option");
+ baseOption.label = WebInspector.UIString("Compared to %s", list[i].title);
+ this.baseSelectElement.appendChild(baseOption);
+ }
+ },
+
+ _updatePercentButton: function()
+ {
+ if (this._isShowingAsPercent) {
+ this.percentButton.title = WebInspector.UIString("Show absolute counts and sizes.");
+ this.percentButton.toggled = true;
+ } else {
+ this.percentButton.title = WebInspector.UIString("Show counts and sizes as percentages.");
+ this.percentButton.toggled = false;
+ }
+ },
+
+ _updateSummaryGraph: function()
+ {
+ this.countsSummaryBar.calculator.showAsPercent = this._isShowingAsPercent;
+ this.countsSummaryBar.update(this.profile.lowlevels);
+
+ this.sizesSummaryBar.calculator.showAsPercent = this._isShowingAsPercent;
+ this.sizesSummaryBar.update(this.profile.lowlevels);
+ }
+};
+
+WebInspector.HeapSnapshotView.prototype.__proto__ = WebInspector.View.prototype;
+
+WebInspector.HeapSnapshotView.SearchHelper = {
+ // In comparators, we assume that a value from a node is passed as the first parameter.
+ operations: { LESS: function (a, b) { return a !== null && a < b; },
+ LESS_OR_EQUAL: function (a, b) { return a !== null && a <= b; },
+ EQUAL: function (a, b) { return a !== null && a === b; },
+ GREATER_OR_EQUAL: function (a, b) { return a !== null && a >= b; },
+ GREATER: function (a, b) { return a !== null && a > b; } },
+
+ operationParsers: { LESS: /^<(\d+)/,
+ LESS_OR_EQUAL: /^<=(\d+)/,
+ GREATER_OR_EQUAL: /^>=(\d+)/,
+ GREATER: /^>(\d+)/ },
+
+ parseOperationAndNumber: function(query)
+ {
+ var operations = WebInspector.HeapSnapshotView.SearchHelper.operations;
+ var parsers = WebInspector.HeapSnapshotView.SearchHelper.operationParsers;
+ for (var operation in parsers) {
+ var match = query.match(parsers[operation]);
+ if (match !== null)
+ return [operations[operation], parseFloat(match[1])];
+ }
+ return [operations.EQUAL, parseFloat(query)];
+ },
+
+ percents: /%$/,
+
+ megaBytes: /MB$/i,
+
+ kiloBytes: /KB$/i,
+
+ bytes: /B$/i
+}
+
+WebInspector.HeapSummaryCalculator = function(lowLevelField)
+{
+ this.total = 1;
+ this.lowLevelField = lowLevelField;
+}
+
+WebInspector.HeapSummaryCalculator.prototype = {
+ computeSummaryValues: function(lowLevels)
+ {
+ var highLevels = {data: 0, code: 0};
+ this.total = 0;
+ for (var item in lowLevels) {
+ var highItem = this._highFromLow(item);
+ if (highItem) {
+ var value = lowLevels[item][this.lowLevelField];
+ highLevels[highItem] += value;
+ this.total += value;
+ }
+ }
+ var result = {categoryValues: highLevels};
+ if (!this.showAsPercent)
+ result.total = this.total;
+ return result;
+ },
+
+ formatValue: function(value)
+ {
+ if (this.showAsPercent)
+ return WebInspector.UIString("%.2f%%", value / this.total * 100.0);
+ else
+ return this._valueToString(value);
+ },
+
+ get showAsPercent()
+ {
+ return this._showAsPercent;
+ },
+
+ set showAsPercent(x)
+ {
+ this._showAsPercent = x;
+ }
+}
+
+WebInspector.HeapSummaryCountCalculator = function()
+{
+ WebInspector.HeapSummaryCalculator.call(this, "count");
+}
+
+WebInspector.HeapSummaryCountCalculator.prototype = {
+ _highFromLow: function(type) {
+ if (type === "CODE_TYPE" || type === "SHARED_FUNCTION_INFO_TYPE" || type === "SCRIPT_TYPE") return "code";
+ if (type === "STRING_TYPE" || type === "HEAP_NUMBER_TYPE" || type.match(/^JS_/)) return "data";
+ return null;
+ },
+
+ _valueToString: function(value) {
+ return value.toString();
+ }
+}
+
+WebInspector.HeapSummaryCountCalculator.prototype.__proto__ = WebInspector.HeapSummaryCalculator.prototype;
+
+WebInspector.HeapSummarySizeCalculator = function()
+{
+ WebInspector.HeapSummaryCalculator.call(this, "size");
+}
+
+WebInspector.HeapSummarySizeCalculator.prototype = {
+ _highFromLow: function(type) {
+ if (type === "CODE_TYPE" || type === "SHARED_FUNCTION_INFO_TYPE" || type === "SCRIPT_TYPE") return "code";
+ if (type === "STRING_TYPE" || type === "HEAP_NUMBER_TYPE" || type.match(/^JS_/) || type.match(/_ARRAY_TYPE$/)) return "data";
+ return null;
+ },
+
+ _valueToString: Number.bytesToString
+}
+
+WebInspector.HeapSummarySizeCalculator.prototype.__proto__ = WebInspector.HeapSummaryCalculator.prototype;
+
+WebInspector.HeapSnapshotSidebarTreeElement = function(snapshot)
+{
+ this.profile = snapshot;
+
+ WebInspector.SidebarTreeElement.call(this, "heap-snapshot-sidebar-tree-item", "", "", snapshot, false);
+
+ this.refreshTitles();
+};
+
+WebInspector.HeapSnapshotSidebarTreeElement.prototype = {
+ get mainTitle()
+ {
+ if (this._mainTitle)
+ return this._mainTitle;
+ return this.profile.title;
+ },
+
+ set mainTitle(x)
+ {
+ this._mainTitle = x;
+ this.refreshTitles();
+ }
+};
+
+WebInspector.HeapSnapshotSidebarTreeElement.prototype.__proto__ = WebInspector.ProfileSidebarTreeElement.prototype;
+
+WebInspector.HeapSnapshotDataGridNodeWithRetainers = function(owningTree)
+{
+ this.tree = owningTree;
+
+ WebInspector.DataGridNode.call(this, null, this._hasRetainers);
+
+ this.addEventListener("populate", this._populate, this);
+};
+
+WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype = {
+ isEmptySet: function(set)
+ {
+ for (var x in set)
+ return false;
+ return true;
+ },
+
+ get _hasRetainers()
+ {
+ return !this.isEmptySet(this.retainers);
+ },
+
+ get _parent()
+ {
+ // For top-level nodes, return owning tree as a parent, not data grid.
+ return this.parent !== this.dataGrid ? this.parent : this.tree;
+ },
+
+ _populate: function(event)
+ {
+ var self = this;
+ this.produceDiff(this.baseRetainers, this.retainers, function(baseItem, snapshotItem) {
+ self.appendChild(new WebInspector.HeapSnapshotDataGridRetainerNode(self.snapshotView, baseItem, snapshotItem, self.tree));
+ });
+
+ if (this._parent) {
+ var currentComparator = this._parent.lastComparator;
+ if (currentComparator)
+ this.sort(currentComparator, true);
+ }
+
+ this.removeEventListener("populate", this._populate, this);
+ },
+
+ produceDiff: function(baseEntries, currentEntries, callback)
+ {
+ for (var item in currentEntries)
+ callback(baseEntries[item], currentEntries[item]);
+
+ for (item in baseEntries) {
+ if (!(item in currentEntries))
+ callback(baseEntries[item], null);
+ }
+ },
+
+ sort: function(comparator, force) {
+ if (!force && this.lastComparator === comparator)
+ return;
+
+ this.children.sort(comparator);
+ var childCount = this.children.length;
+ for (var childIndex = 0; childIndex < childCount; ++childIndex)
+ this.children[childIndex]._recalculateSiblings(childIndex);
+ for (var i = 0; i < this.children.length; ++i) {
+ var child = this.children[i];
+ if (!force && (!child.expanded || child.lastComparator === comparator))
+ continue;
+ child.sort(comparator, force);
+ }
+ this.lastComparator = comparator;
+ },
+
+ signForDelta: function(delta) {
+ if (delta === 0)
+ return "";
+ if (delta > 0)
+ return "+";
+ else
+ // Math minus sign, same width as plus.
+ return "\u2212";
+ },
+
+ showDeltaAsPercent: function(value) {
+ if (value === Number.POSITIVE_INFINITY)
+ return WebInspector.UIString("new");
+ else if (value === Number.NEGATIVE_INFINITY)
+ return WebInspector.UIString("deleted");
+ if (value > 1000.0)
+ return WebInspector.UIString("%s >1000%%", this.signForDelta(value));
+ return WebInspector.UIString("%s%.2f%%", this.signForDelta(value), Math.abs(value));
+ },
+
+ getTotalCount: function() {
+ if (!this._count) {
+ this._count = 0;
+ for (var i = 0, n = this.children.length; i < n; ++i)
+ this._count += this.children[i].count;
+ }
+ return this._count;
+ },
+
+ getTotalSize: function() {
+ if (!this._size) {
+ this._size = 0;
+ for (var i = 0, n = this.children.length; i < n; ++i)
+ this._size += this.children[i].size;
+ }
+ return this._size;
+ },
+
+ get countPercent()
+ {
+ return this.count / this._parent.getTotalCount() * 100.0;
+ },
+
+ get sizePercent()
+ {
+ return this.size / this._parent.getTotalSize() * 100.0;
+ },
+
+ get countDeltaPercent()
+ {
+ if (this.baseCount > 0) {
+ if (this.count > 0)
+ return this.countDelta / this.baseCount * 100.0;
+ else
+ return Number.NEGATIVE_INFINITY;
+ } else
+ return Number.POSITIVE_INFINITY;
+ },
+
+ get sizeDeltaPercent()
+ {
+ if (this.baseSize > 0) {
+ if (this.size > 0)
+ return this.sizeDelta / this.baseSize * 100.0;
+ else
+ return Number.NEGATIVE_INFINITY;
+ } else
+ return Number.POSITIVE_INFINITY;
+ },
+
+ get data()
+ {
+ var data = {};
+
+ data["cons"] = this.constructorName;
+
+ if (this.snapshotView.showCountAsPercent)
+ data["count"] = WebInspector.UIString("%.2f%%", this.countPercent);
+ else
+ data["count"] = this.count;
+
+ if (this.size !== null) {
+ if (this.snapshotView.showSizeAsPercent)
+ data["size"] = WebInspector.UIString("%.2f%%", this.sizePercent);
+ else
+ data["size"] = Number.bytesToString(this.size);
+ } else
+ data["size"] = "";
+
+ if (this.snapshotView.showCountDeltaAsPercent)
+ data["countDelta"] = this.showDeltaAsPercent(this.countDeltaPercent);
+ else
+ data["countDelta"] = WebInspector.UIString("%s%d", this.signForDelta(this.countDelta), Math.abs(this.countDelta));
+
+ if (this.sizeDelta !== null) {
+ if (this.snapshotView.showSizeDeltaAsPercent)
+ data["sizeDelta"] = this.showDeltaAsPercent(this.sizeDeltaPercent);
+ else
+ data["sizeDelta"] = WebInspector.UIString("%s%s", this.signForDelta(this.sizeDelta), Number.bytesToString(Math.abs(this.sizeDelta)));
+ } else
+ data["sizeDelta"] = "";
+
+ return data;
+ },
+
+ createCell: function(columnIdentifier)
+ {
+ var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
+
+ if ((columnIdentifier === "cons" && this._searchMatchedConsColumn) ||
+ (columnIdentifier === "count" && this._searchMatchedCountColumn) ||
+ (columnIdentifier === "size" && this._searchMatchedSizeColumn) ||
+ (columnIdentifier === "countDelta" && this._searchMatchedCountDeltaColumn) ||
+ (columnIdentifier === "sizeDelta" && this._searchMatchedSizeDeltaColumn))
+ cell.addStyleClass("highlight");
+
+ return cell;
+ }
+};
+
+WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.__proto__ = WebInspector.DataGridNode.prototype;
+
+WebInspector.HeapSnapshotDataGridNode = function(snapshotView, baseEntry, snapshotEntry, owningTree)
+{
+ this.snapshotView = snapshotView;
+
+ if (!snapshotEntry)
+ snapshotEntry = { cons: baseEntry.cons, count: 0, size: 0, retainers: {} };
+ this.constructorName = snapshotEntry.cons;
+ this.count = snapshotEntry.count;
+ this.size = snapshotEntry.size;
+ this.retainers = snapshotEntry.retainers;
+
+ if (!baseEntry)
+ baseEntry = { count: 0, size: 0, retainers: {} };
+ this.baseCount = baseEntry.count;
+ this.countDelta = this.count - this.baseCount;
+ this.baseSize = baseEntry.size;
+ this.sizeDelta = this.size - this.baseSize;
+ this.baseRetainers = baseEntry.retainers;
+
+ WebInspector.HeapSnapshotDataGridNodeWithRetainers.call(this, owningTree);
+};
+
+WebInspector.HeapSnapshotDataGridNode.prototype.__proto__ = WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype;
+
+WebInspector.HeapSnapshotDataGridList = function(snapshotView, baseEntries, snapshotEntries)
+{
+ this.tree = this;
+ this.snapshotView = snapshotView;
+ this.children = [];
+ this.lastComparator = null;
+ this.populateChildren(baseEntries, snapshotEntries);
+};
+
+WebInspector.HeapSnapshotDataGridList.prototype = {
+ appendChild: function(child)
+ {
+ this.insertChild(child, this.children.length);
+ },
+
+ insertChild: function(child, index)
+ {
+ this.children.splice(index, 0, child);
+ },
+
+ removeChildren: function()
+ {
+ this.children = [];
+ },
+
+ populateChildren: function(baseEntries, snapshotEntries)
+ {
+ var self = this;
+ this.produceDiff(baseEntries, snapshotEntries, function(baseItem, snapshotItem) {
+ self.appendChild(new WebInspector.HeapSnapshotDataGridNode(self.snapshotView, baseItem, snapshotItem, self));
+ });
+ },
+
+ produceDiff: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.produceDiff,
+ sort: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.sort,
+ getTotalCount: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalCount,
+ getTotalSize: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalSize
+};
+
+WebInspector.HeapSnapshotDataGridList.propertyComparators = [{}, {}];
+
+WebInspector.HeapSnapshotDataGridList.propertyComparator = function(property, property2, isAscending)
+{
+ var propertyHash = property + "#" + property2;
+ var comparator = this.propertyComparators[(isAscending ? 1 : 0)][propertyHash];
+ if (!comparator) {
+ comparator = function(lhs, rhs) {
+ var l = lhs[property], r = rhs[property];
+ if ((l === null || r === null) && property2 !== null)
+ l = lhs[property2], r = rhs[property2];
+ var result = l < r ? -1 : (l > r ? 1 : 0);
+ return isAscending ? result : -result;
+ };
+ this.propertyComparators[(isAscending ? 1 : 0)][propertyHash] = comparator;
+ }
+ return comparator;
+};
+
+WebInspector.HeapSnapshotDataGridRetainerNode = function(snapshotView, baseEntry, snapshotEntry, owningTree)
+{
+ this.snapshotView = snapshotView;
+
+ if (!snapshotEntry)
+ snapshotEntry = { cons: baseEntry.cons, count: 0, clusters: {} };
+ this.constructorName = snapshotEntry.cons;
+ this.count = snapshotEntry.count;
+ this.retainers = this._calculateRetainers(this.snapshotView.profile, snapshotEntry.clusters);
+
+ if (!baseEntry)
+ baseEntry = { count: 0, clusters: {} };
+ this.baseCount = baseEntry.count;
+ this.countDelta = this.count - this.baseCount;
+ this.baseRetainers = this._calculateRetainers(this.snapshotView.baseSnapshot, baseEntry.clusters);
+
+ this.size = null;
+ this.sizeDelta = null;
+
+ WebInspector.HeapSnapshotDataGridNodeWithRetainers.call(this, owningTree);
+}
+
+WebInspector.HeapSnapshotDataGridRetainerNode.prototype = {
+ get sizePercent()
+ {
+ return null;
+ },
+
+ get sizeDeltaPercent()
+ {
+ return null;
+ },
+
+ _calculateRetainers: function(snapshot, clusters) {
+ var retainers = {};
+ if (this.isEmptySet(clusters)) {
+ if (this.constructorName in snapshot.entries)
+ return snapshot.entries[this.constructorName].retainers;
+ } else {
+ // In case when an entry is retained by clusters, we need to gather up the list
+ // of retainers by merging retainers of every cluster.
+ // E.g. having such a tree:
+ // A
+ // Object:1 10
+ // X 3
+ // Y 4
+ // Object:2 5
+ // X 6
+ //
+ // will result in a following retainers list: X 9, Y 4.
+ for (var clusterName in clusters) {
+ if (clusterName in snapshot.clusters) {
+ var clusterRetainers = snapshot.clusters[clusterName].retainers;
+ for (var clusterRetainer in clusterRetainers) {
+ var clusterRetainerEntry = clusterRetainers[clusterRetainer];
+ if (!(clusterRetainer in retainers))
+ retainers[clusterRetainer] = { cons: clusterRetainerEntry.cons, count: 0, clusters: {} };
+ retainers[clusterRetainer].count += clusterRetainerEntry.count;
+ for (var clusterRetainerCluster in clusterRetainerEntry.clusters)
+ retainers[clusterRetainer].clusters[clusterRetainerCluster] = true;
+ }
+ }
+ }
+ }
+ return retainers;
+ }
+};
+
+WebInspector.HeapSnapshotDataGridRetainerNode.prototype.__proto__ = WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype;
+
+
+WebInspector.HeapSnapshotProfileType = function()
+{
+ WebInspector.ProfileType.call(this, WebInspector.HeapSnapshotProfileType.TypeId, WebInspector.UIString("HEAP SNAPSHOTS"));
+}
+
+WebInspector.HeapSnapshotProfileType.TypeId = "HEAP";
+
+WebInspector.HeapSnapshotProfileType.snapshots = [];
+
+WebInspector.HeapSnapshotProfileType.prototype = {
+ get buttonTooltip()
+ {
+ return WebInspector.UIString("Take heap snapshot.");
+ },
+
+ get buttonStyle()
+ {
+ return "heap-snapshot-status-bar-item status-bar-item";
+ },
+
+ buttonClicked: function()
+ {
+ InspectorBackend.takeHeapSnapshot();
+ },
+
+ get welcomeMessage()
+ {
+ return WebInspector.UIString("Get a heap snapshot by pressing<br>the %s button on the status bar.");
+ },
+
+ createSidebarTreeElementForProfile: function(profile)
+ {
+ var element = new WebInspector.HeapSnapshotSidebarTreeElement(profile);
+ element.small = false;
+ return element;
+ },
+
+ createView: function(profile)
+ {
+ return new WebInspector.HeapSnapshotView(WebInspector.panels.profiles, profile);
+ }
+}
+
+WebInspector.HeapSnapshotProfileType.prototype.__proto__ = WebInspector.ProfileType.prototype;
+
+
+(function() {
+ var originalCreatePanels = WebInspector._createPanels;
+ WebInspector._createPanels = function() {
+ originalCreatePanels.apply(this, arguments);
+ if (WebInspector.panels.profiles)
+ WebInspector.panels.profiles.registerProfileType(new WebInspector.HeapSnapshotProfileType());
+ }
+})();
diff --git a/WebKit/chromium/src/js/Images/segmentChromium.png b/WebKit/chromium/src/js/Images/segmentChromium.png
new file mode 100755
index 0000000..607559b
--- /dev/null
+++ b/WebKit/chromium/src/js/Images/segmentChromium.png
Binary files differ
diff --git a/WebKit/chromium/src/js/Images/segmentHoverChromium.png b/WebKit/chromium/src/js/Images/segmentHoverChromium.png
new file mode 100755
index 0000000..0a743d9
--- /dev/null
+++ b/WebKit/chromium/src/js/Images/segmentHoverChromium.png
Binary files differ
diff --git a/WebKit/chromium/src/js/Images/segmentHoverEndChromium.png b/WebKit/chromium/src/js/Images/segmentHoverEndChromium.png
new file mode 100755
index 0000000..cf62072
--- /dev/null
+++ b/WebKit/chromium/src/js/Images/segmentHoverEndChromium.png
Binary files differ
diff --git a/WebKit/chromium/src/js/Images/segmentSelectedChromium.png b/WebKit/chromium/src/js/Images/segmentSelectedChromium.png
new file mode 100755
index 0000000..a1f7251
--- /dev/null
+++ b/WebKit/chromium/src/js/Images/segmentSelectedChromium.png
Binary files differ
diff --git a/WebKit/chromium/src/js/Images/segmentSelectedEndChromium.png b/WebKit/chromium/src/js/Images/segmentSelectedEndChromium.png
new file mode 100755
index 0000000..07641db
--- /dev/null
+++ b/WebKit/chromium/src/js/Images/segmentSelectedEndChromium.png
Binary files differ
diff --git a/WebKit/chromium/src/js/Images/statusbarBackgroundChromium.png b/WebKit/chromium/src/js/Images/statusbarBackgroundChromium.png
new file mode 100755
index 0000000..9d326ac
--- /dev/null
+++ b/WebKit/chromium/src/js/Images/statusbarBackgroundChromium.png
Binary files differ
diff --git a/WebKit/chromium/src/js/Images/statusbarBottomBackgroundChromium.png b/WebKit/chromium/src/js/Images/statusbarBottomBackgroundChromium.png
new file mode 100755
index 0000000..7c7db0a
--- /dev/null
+++ b/WebKit/chromium/src/js/Images/statusbarBottomBackgroundChromium.png
Binary files differ
diff --git a/WebKit/chromium/src/js/Images/statusbarButtonsChromium.png b/WebKit/chromium/src/js/Images/statusbarButtonsChromium.png
new file mode 100755
index 0000000..0c6635d
--- /dev/null
+++ b/WebKit/chromium/src/js/Images/statusbarButtonsChromium.png
Binary files differ
diff --git a/WebKit/chromium/src/js/Images/statusbarMenuButtonChromium.png b/WebKit/chromium/src/js/Images/statusbarMenuButtonChromium.png
new file mode 100755
index 0000000..bf26684
--- /dev/null
+++ b/WebKit/chromium/src/js/Images/statusbarMenuButtonChromium.png
Binary files differ
diff --git a/WebKit/chromium/src/js/Images/statusbarMenuButtonSelectedChromium.png b/WebKit/chromium/src/js/Images/statusbarMenuButtonSelectedChromium.png
new file mode 100755
index 0000000..3c0aeec
--- /dev/null
+++ b/WebKit/chromium/src/js/Images/statusbarMenuButtonSelectedChromium.png
Binary files differ
diff --git a/WebKit/chromium/src/js/InjectDispatch.js b/WebKit/chromium/src/js/InjectDispatch.js
new file mode 100644
index 0000000..e070c42
--- /dev/null
+++ b/WebKit/chromium/src/js/InjectDispatch.js
@@ -0,0 +1,106 @@
+/*
+ * 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 Injects "injected" object into the inspectable page.
+ */
+
+
+var InspectorControllerDispatcher = {};
+
+/**
+ * Main dispatch method, all calls from the host to InspectorController go
+ * through this one.
+ * @param {string} functionName Function to call
+ * @param {string} json_args JSON-serialized call parameters.
+ * @return {string} JSON-serialized result of the dispatched call.
+ */
+InspectorControllerDispatcher.dispatch = function(functionName, json_args)
+{
+ var params = JSON.parse(json_args);
+ InspectorBackend[functionName].apply(InspectorBackend, params);
+};
+
+/**
+ * Special controller object for APU related messages. Outgoing messages
+ * are sent to this object if the ApuAgentDispatcher is enabled.
+ **/
+var ApuAgentDispatcher = { enabled : false };
+
+/**
+ * Dispatches messages to APU. This filters and transforms
+ * outgoing messages that are used by APU.
+ * @param {string} method name of the dispatch method.
+ **/
+ApuAgentDispatcher.dispatchToApu = function(method, args)
+{
+ if (method !== "addRecordToTimeline" && method !== "updateResource" && method !== "addResource")
+ return;
+ // TODO(knorton): Transform args so they can be used
+ // by APU.
+ DevToolsAgentHost.dispatchToApu(JSON.stringify(args));
+};
+
+/**
+ * This is called by the InspectorFrontend for serialization.
+ * We serialize the call and send it to the client over the IPC
+ * using dispatchOut bound method.
+ */
+function dispatch(method, var_args) {
+ // Handle all messages with non-primitieve arguments here.
+ var args = Array.prototype.slice.call(arguments);
+
+ if (method === "inspectedWindowCleared" || method === "reset" || method === "setAttachedWindow") {
+ // Filter out messages we don't need here.
+ // We do it on the sender side since they may have non-serializable
+ // parameters.
+ return;
+ }
+
+ // Sniff some inspector controller state changes in order to support
+ // cross-navigation instrumentation. Keep names in sync with
+ // webdevtoolsagent_impl.
+ if (method === "timelineProfilerWasStarted")
+ DevToolsAgentHost.runtimeFeatureStateChanged("timeline-profiler", true);
+ else if (method === "timelineProfilerWasStopped")
+ DevToolsAgentHost.runtimeFeatureStateChanged("timeline-profiler", false);
+ else if (method === "resourceTrackingWasEnabled")
+ DevToolsAgentHost.runtimeFeatureStateChanged("resource-tracking", true);
+ else if (method === "resourceTrackingWasDisabled")
+ DevToolsAgentHost.runtimeFeatureStateChanged("resource-tracking", false);
+
+ if (ApuAgentDispatcher.enabled) {
+ ApuAgentDispatcher.dispatchToApu(method, args);
+ return;
+ }
+
+ var call = JSON.stringify(args);
+ DevToolsAgentHost.dispatch(call);
+};
diff --git a/WebKit/chromium/src/js/InspectorControllerImpl.js b/WebKit/chromium/src/js/InspectorControllerImpl.js
new file mode 100644
index 0000000..c92a94c
--- /dev/null
+++ b/WebKit/chromium/src/js/InspectorControllerImpl.js
@@ -0,0 +1,279 @@
+/*
+ * 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 DevTools' implementation of the InspectorController API.
+ */
+
+if (!this.devtools)
+ devtools = {};
+
+devtools.InspectorBackendImpl = function()
+{
+ WebInspector.InspectorBackendStub.call(this);
+ this.installInspectorControllerDelegate_("clearMessages");
+ this.installInspectorControllerDelegate_("copyNode");
+ this.installInspectorControllerDelegate_("deleteCookie");
+ this.installInspectorControllerDelegate_("didEvaluateForTestInFrontend");
+ this.installInspectorControllerDelegate_("disableResourceTracking");
+ this.installInspectorControllerDelegate_("disableTimeline");
+ this.installInspectorControllerDelegate_("enableResourceTracking");
+ this.installInspectorControllerDelegate_("enableTimeline");
+ this.installInspectorControllerDelegate_("getChildNodes");
+ this.installInspectorControllerDelegate_("getCookies");
+ this.installInspectorControllerDelegate_("getDatabaseTableNames");
+ this.installInspectorControllerDelegate_("getDOMStorageEntries");
+ this.installInspectorControllerDelegate_("getEventListenersForNode");
+ this.installInspectorControllerDelegate_("getResourceContent");
+ this.installInspectorControllerDelegate_("highlightDOMNode");
+ this.installInspectorControllerDelegate_("hideDOMNodeHighlight");
+ this.installInspectorControllerDelegate_("releaseWrapperObjectGroup");
+ this.installInspectorControllerDelegate_("removeAttribute");
+ this.installInspectorControllerDelegate_("removeDOMStorageItem");
+ this.installInspectorControllerDelegate_("removeNode");
+ this.installInspectorControllerDelegate_("saveFrontendSettings");
+ this.installInspectorControllerDelegate_("setAttribute");
+ this.installInspectorControllerDelegate_("setDOMStorageItem");
+ this.installInspectorControllerDelegate_("setInjectedScriptSource");
+ this.installInspectorControllerDelegate_("setTextNodeValue");
+ this.installInspectorControllerDelegate_("startTimelineProfiler");
+ this.installInspectorControllerDelegate_("stopTimelineProfiler");
+ this.installInspectorControllerDelegate_("storeLastActivePanel");
+};
+devtools.InspectorBackendImpl.prototype.__proto__ = WebInspector.InspectorBackendStub.prototype;
+
+
+/**
+ * {@inheritDoc}.
+ */
+devtools.InspectorBackendImpl.prototype.toggleNodeSearch = function()
+{
+ WebInspector.InspectorBackendStub.prototype.toggleNodeSearch.call(this);
+ this.callInspectorController_.call(this, "toggleNodeSearch");
+ if (!this.searchingForNode()) {
+ // This is called from ElementsPanel treeOutline's focusNodeChanged().
+ DevToolsHost.activateWindow();
+ }
+};
+
+
+/**
+ * @override
+ */
+devtools.InspectorBackendImpl.prototype.debuggerEnabled = function()
+{
+ return true;
+};
+
+
+/**
+ * @override
+ */
+devtools.InspectorBackendImpl.prototype.profilerEnabled = function()
+{
+ return true;
+};
+
+
+devtools.InspectorBackendImpl.prototype.addBreakpoint = function(sourceID, line, condition)
+{
+ devtools.tools.getDebuggerAgent().addBreakpoint(sourceID, line, condition);
+};
+
+
+devtools.InspectorBackendImpl.prototype.removeBreakpoint = function(sourceID, line)
+{
+ devtools.tools.getDebuggerAgent().removeBreakpoint(sourceID, line);
+};
+
+devtools.InspectorBackendImpl.prototype.updateBreakpoint = function(sourceID, line, condition)
+{
+ devtools.tools.getDebuggerAgent().updateBreakpoint(sourceID, line, condition);
+};
+
+devtools.InspectorBackendImpl.prototype.pauseInDebugger = function()
+{
+ devtools.tools.getDebuggerAgent().pauseExecution();
+};
+
+
+devtools.InspectorBackendImpl.prototype.resumeDebugger = function()
+{
+ devtools.tools.getDebuggerAgent().resumeExecution();
+};
+
+
+devtools.InspectorBackendImpl.prototype.stepIntoStatementInDebugger = function()
+{
+ devtools.tools.getDebuggerAgent().stepIntoStatement();
+};
+
+
+devtools.InspectorBackendImpl.prototype.stepOutOfFunctionInDebugger = function()
+{
+ devtools.tools.getDebuggerAgent().stepOutOfFunction();
+};
+
+
+devtools.InspectorBackendImpl.prototype.stepOverStatementInDebugger = function()
+{
+ devtools.tools.getDebuggerAgent().stepOverStatement();
+};
+
+/**
+ * @override
+ */
+devtools.InspectorBackendImpl.prototype.setPauseOnExceptionsState = function(state)
+{
+ this._setPauseOnExceptionsState = state;
+ // TODO(yurys): support all three states. See http://crbug.com/32877
+ var enabled = (state !== WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions);
+ return devtools.tools.getDebuggerAgent().setPauseOnExceptions(enabled);
+};
+
+/**
+ * @override
+ */
+devtools.InspectorBackendImpl.prototype.pauseOnExceptionsState = function()
+{
+ return (this._setPauseOnExceptionsState || WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions);
+};
+
+/**
+ * @override
+ */
+devtools.InspectorBackendImpl.prototype.pauseOnExceptions = function()
+{
+ return devtools.tools.getDebuggerAgent().pauseOnExceptions();
+};
+
+
+/**
+ * @override
+ */
+devtools.InspectorBackendImpl.prototype.setPauseOnExceptions = function(value)
+{
+ return devtools.tools.getDebuggerAgent().setPauseOnExceptions(value);
+};
+
+
+/**
+ * @override
+ */
+devtools.InspectorBackendImpl.prototype.startProfiling = function()
+{
+ devtools.tools.getProfilerAgent().startProfiling(devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_CPU);
+};
+
+
+/**
+ * @override
+ */
+devtools.InspectorBackendImpl.prototype.stopProfiling = function()
+{
+ devtools.tools.getProfilerAgent().stopProfiling( devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_CPU);
+};
+
+
+/**
+ * @override
+ */
+devtools.InspectorBackendImpl.prototype.getProfileHeaders = function(callId)
+{
+ WebInspector.didGetProfileHeaders(callId, []);
+};
+
+
+/**
+ * Emulate WebKit InspectorController behavior. It stores profiles on renderer side,
+ * and is able to retrieve them by uid using "getProfile".
+ */
+devtools.InspectorBackendImpl.prototype.addFullProfile = function(profile)
+{
+ WebInspector.__fullProfiles = WebInspector.__fullProfiles || {};
+ WebInspector.__fullProfiles[profile.uid] = profile;
+};
+
+
+/**
+ * @override
+ */
+devtools.InspectorBackendImpl.prototype.getProfile = function(callId, uid)
+{
+ if (WebInspector.__fullProfiles && (uid in WebInspector.__fullProfiles))
+ WebInspector.didGetProfile(callId, WebInspector.__fullProfiles[uid]);
+};
+
+
+/**
+ * @override
+ */
+devtools.InspectorBackendImpl.prototype.takeHeapSnapshot = function()
+{
+ devtools.tools.getProfilerAgent().startProfiling(devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT
+ | devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_STATS
+ | devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_JS_CONSTRUCTORS);
+};
+
+
+/**
+ * @override
+ */
+devtools.InspectorBackendImpl.prototype.dispatchOnInjectedScript = function(callId, injectedScriptId, methodName, argsString, async)
+{
+ // Encode injectedScriptId into callId
+ if (typeof injectedScriptId !== "number")
+ injectedScriptId = 0;
+ RemoteToolsAgent.dispatchOnInjectedScript(callId, injectedScriptId, methodName, argsString, async);
+};
+
+
+/**
+ * Installs delegating handler into the inspector controller.
+ * @param {string} methodName Method to install delegating handler for.
+ */
+devtools.InspectorBackendImpl.prototype.installInspectorControllerDelegate_ = function(methodName)
+{
+ this[methodName] = this.callInspectorController_.bind(this, methodName);
+};
+
+
+/**
+ * Bound function with the installInjectedScriptDelegate_ actual
+ * implementation.
+ */
+devtools.InspectorBackendImpl.prototype.callInspectorController_ = function(methodName, var_arg)
+{
+ var args = Array.prototype.slice.call(arguments, 1);
+ RemoteToolsAgent.dispatchOnInspectorController(WebInspector.Callback.wrap(function(){}), methodName, JSON.stringify(args));
+};
+
+
+InspectorBackend = new devtools.InspectorBackendImpl();
diff --git a/WebKit/chromium/src/js/ProfilerAgent.js b/WebKit/chromium/src/js/ProfilerAgent.js
new file mode 100644
index 0000000..e08c5d2
--- /dev/null
+++ b/WebKit/chromium/src/js/ProfilerAgent.js
@@ -0,0 +1,227 @@
+/*
+ * 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 Provides communication interface to remote v8 profiler.
+ */
+
+/**
+ * @constructor
+ */
+devtools.ProfilerAgent = function()
+{
+ RemoteProfilerAgent.didGetActiveProfilerModules = this._didGetActiveProfilerModules.bind(this);
+ RemoteProfilerAgent.didGetLogLines = this._didGetLogLines.bind(this);
+
+ /**
+ * Active profiler modules flags.
+ * @type {number}
+ */
+ this._activeProfilerModules = devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE;
+
+ /**
+ * Interval for polling profiler state.
+ * @type {number}
+ */
+ this._getActiveProfilerModulesInterval = null;
+
+ /**
+ * Profiler log position.
+ * @type {number}
+ */
+ this._logPosition = 0;
+
+ /**
+ * Last requested log position.
+ * @type {number}
+ */
+ this._lastRequestedLogPosition = -1;
+
+ /**
+ * Whether log contents retrieval must be forced next time.
+ * @type {boolean}
+ */
+ this._forceGetLogLines = false;
+
+ /**
+ * Profiler processor instance.
+ * @type {devtools.profiler.Processor}
+ */
+ this._profilerProcessor = new devtools.profiler.Processor();
+};
+
+
+/**
+ * A copy of enum from include/v8.h
+ * @enum {number}
+ */
+devtools.ProfilerAgent.ProfilerModules = {
+ PROFILER_MODULE_NONE: 0,
+ PROFILER_MODULE_CPU: 1,
+ PROFILER_MODULE_HEAP_STATS: 1 << 1,
+ PROFILER_MODULE_JS_CONSTRUCTORS: 1 << 2,
+ PROFILER_MODULE_HEAP_SNAPSHOT: 1 << 16
+};
+
+
+/**
+ * Sets up callbacks that deal with profiles processing.
+ */
+devtools.ProfilerAgent.prototype.setupProfilerProcessorCallbacks = function()
+{
+ // A temporary icon indicating that the profile is being processed.
+ var processingIcon = new WebInspector.SidebarTreeElement(
+ "profile-sidebar-tree-item",
+ WebInspector.UIString("Processing..."),
+ '', null, false);
+ var profilesSidebar = WebInspector.panels.profiles.getProfileType(WebInspector.CPUProfileType.TypeId).treeElement;
+
+ this._profilerProcessor.setCallbacks(
+ function onProfileProcessingStarted() {
+ // Set visually empty string. Subtitle hiding is done via styles
+ // manipulation which doesn't play well with dynamic append / removal.
+ processingIcon.subtitle = " ";
+ profilesSidebar.appendChild(processingIcon);
+ },
+ function onProfileProcessingStatus(ticksCount) {
+ processingIcon.subtitle = WebInspector.UIString("%d ticks processed", ticksCount);
+ },
+ function onProfileProcessingFinished(profile) {
+ profilesSidebar.removeChild(processingIcon);
+ profile.typeId = WebInspector.CPUProfileType.TypeId;
+ InspectorBackend.addFullProfile(profile);
+ WebInspector.addProfileHeader(profile);
+ // If no profile is currently shown, show the new one.
+ var profilesPanel = WebInspector.panels.profiles;
+ if (!profilesPanel.visibleView) {
+ profilesPanel.showProfile(profile);
+ }
+ }
+ );
+};
+
+
+/**
+ * Initializes profiling state.
+ */
+devtools.ProfilerAgent.prototype.initializeProfiling = function()
+{
+ this.setupProfilerProcessorCallbacks();
+ this._forceGetLogLines = true;
+ this._getActiveProfilerModulesInterval = setInterval(function() { RemoteProfilerAgent.getActiveProfilerModules(); }, 1000);
+};
+
+
+/**
+ * Requests the next chunk of log lines.
+ * @param {boolean} immediately Do not postpone the request.
+ * @private
+ */
+devtools.ProfilerAgent.prototype._getNextLogLines = function(immediately)
+{
+ if (this._lastRequestedLogPosition == this._logPosition)
+ return;
+ var pos = this._lastRequestedLogPosition = this._logPosition;
+ if (immediately)
+ RemoteProfilerAgent.getLogLines(pos);
+ else
+ setTimeout(function() { RemoteProfilerAgent.getLogLines(pos); }, 500);
+};
+
+
+/**
+ * Starts profiling.
+ * @param {number} modules List of modules to enable.
+ */
+devtools.ProfilerAgent.prototype.startProfiling = function(modules)
+{
+ var cmd = new devtools.DebugCommand("profile", {
+ "modules": modules,
+ "command": "resume"});
+ devtools.DebuggerAgent.sendCommand_(cmd);
+ RemoteDebuggerAgent.processDebugCommands();
+ if (modules & devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT) {
+ // Active modules will not change, instead, a snapshot will be logged.
+ this._getNextLogLines();
+ }
+};
+
+
+/**
+ * Stops profiling.
+ */
+devtools.ProfilerAgent.prototype.stopProfiling = function(modules)
+{
+ var cmd = new devtools.DebugCommand("profile", {
+ "modules": modules,
+ "command": "pause"});
+ devtools.DebuggerAgent.sendCommand_(cmd);
+ RemoteDebuggerAgent.processDebugCommands();
+};
+
+
+/**
+ * Handles current profiler status.
+ * @param {number} modules List of active (started) modules.
+ */
+devtools.ProfilerAgent.prototype._didGetActiveProfilerModules = function(modules)
+{
+ var profModules = devtools.ProfilerAgent.ProfilerModules;
+ var profModuleNone = profModules.PROFILER_MODULE_NONE;
+ if (this._forceGetLogLines || (modules !== profModuleNone && this._activeProfilerModules === profModuleNone)) {
+ this._forceGetLogLines = false;
+ // Start to query log data.
+ this._getNextLogLines(true);
+ }
+ this._activeProfilerModules = modules;
+ // Update buttons.
+ WebInspector.setRecordingProfile(modules & profModules.PROFILER_MODULE_CPU);
+};
+
+
+/**
+ * Handles a portion of a profiler log retrieved by getLogLines call.
+ * @param {number} pos Current position in log.
+ * @param {string} log A portion of profiler log.
+ */
+devtools.ProfilerAgent.prototype._didGetLogLines = function(pos, log)
+{
+ this._logPosition = pos;
+ if (log.length > 0)
+ this._profilerProcessor.processLogChunk(log);
+ else {
+ // Allow re-reading from the last position.
+ this._lastRequestedLogPosition = this._logPosition - 1;
+ if (this._activeProfilerModules === devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE)
+ // No new data and profiling is stopped---suspend log reading.
+ return;
+ }
+ this._getNextLogLines();
+};
diff --git a/WebKit/chromium/src/js/ProfilerProcessor.js b/WebKit/chromium/src/js/ProfilerProcessor.js
new file mode 100644
index 0000000..f678d2c
--- /dev/null
+++ b/WebKit/chromium/src/js/ProfilerProcessor.js
@@ -0,0 +1,543 @@
+/*
+ * 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 Profiler processor is used to process log file produced
+ * by V8 and produce an internal profile representation which is used
+ * for building profile views in "Profiles" tab.
+ */
+
+
+/**
+ * Creates a Profile View builder object compatible with WebKit Profiler UI.
+ *
+ * @param {number} samplingRate Number of ms between profiler ticks.
+ * @constructor
+ */
+devtools.profiler.WebKitViewBuilder = function(samplingRate)
+{
+ devtools.profiler.ViewBuilder.call(this, samplingRate);
+};
+devtools.profiler.WebKitViewBuilder.prototype.__proto__ = devtools.profiler.ViewBuilder.prototype;
+
+
+/**
+ * @override
+ */
+devtools.profiler.WebKitViewBuilder.prototype.createViewNode = function(funcName, totalTime, selfTime, head)
+{
+ return new devtools.profiler.WebKitViewNode(funcName, totalTime, selfTime, head);
+};
+
+
+/**
+ * Constructs a Profile View node object for displaying in WebKit Profiler UI.
+ *
+ * @param {string} internalFuncName A fully qualified function name.
+ * @param {number} totalTime Amount of time that application spent in the
+ * corresponding function and its descendants (not that depending on
+ * profile they can be either callees or callers.)
+ * @param {number} selfTime Amount of time that application spent in the
+ * corresponding function only.
+ * @param {devtools.profiler.ProfileView.Node} head Profile view head.
+ * @constructor
+ */
+devtools.profiler.WebKitViewNode = function(internalFuncName, totalTime, selfTime, head)
+{
+ devtools.profiler.ProfileView.Node.call(this, internalFuncName, totalTime, selfTime, head);
+ this.initFuncInfo_();
+ this.callUID = internalFuncName;
+};
+devtools.profiler.WebKitViewNode.prototype.__proto__ = devtools.profiler.ProfileView.Node.prototype;
+
+
+/**
+ * RegEx for stripping V8's prefixes of compiled functions.
+ */
+devtools.profiler.WebKitViewNode.FUNC_NAME_STRIP_RE = /^(?:LazyCompile|Function|Callback): (.*)$/;
+
+
+/**
+ * RegEx for extracting script source URL and line number.
+ */
+devtools.profiler.WebKitViewNode.FUNC_NAME_PARSE_RE = /^((?:get | set )?[^ ]+) (.*):(\d+)( \{\d+\})?$/;
+
+
+/**
+ * Inits "functionName", "url", and "lineNumber" fields using "internalFuncName"
+ * field.
+ * @private
+ */
+devtools.profiler.WebKitViewNode.prototype.initFuncInfo_ = function()
+{
+ var nodeAlias = devtools.profiler.WebKitViewNode;
+ this.functionName = this.internalFuncName;
+
+ var strippedName = nodeAlias.FUNC_NAME_STRIP_RE.exec(this.functionName);
+ if (strippedName)
+ this.functionName = strippedName[1];
+
+ var parsedName = nodeAlias.FUNC_NAME_PARSE_RE.exec(this.functionName);
+ if (parsedName) {
+ this.functionName = parsedName[1];
+ if (parsedName[4])
+ this.functionName += parsedName[4];
+ this.url = parsedName[2];
+ this.lineNumber = parsedName[3];
+ } else {
+ this.url = '';
+ this.lineNumber = 0;
+ }
+};
+
+
+/**
+ * Ancestor of a profile object that leaves out only JS-related functions.
+ * @constructor
+ */
+devtools.profiler.JsProfile = function()
+{
+ devtools.profiler.Profile.call(this);
+};
+devtools.profiler.JsProfile.prototype.__proto__ = devtools.profiler.Profile.prototype;
+
+
+/**
+ * RegExp that leaves only non-native JS functions.
+ * @type {RegExp}
+ */
+devtools.profiler.JsProfile.JS_NON_NATIVE_RE = new RegExp(
+ "^" +
+ "(?:Callback:)|" +
+ "(?:Script: (?!native))|" +
+ "(?:(?:LazyCompile|Function): [^ ]*(?: (?!native )[^ ]+:\\d+)?$)");
+
+
+/**
+ * @override
+ */
+devtools.profiler.JsProfile.prototype.skipThisFunction = function(name)
+{
+ return !devtools.profiler.JsProfile.JS_NON_NATIVE_RE.test(name);
+};
+
+
+/**
+ * Profiler processor. Consumes profiler log and builds profile views.
+ * FIXME: change field naming style to use trailing underscore.
+ *
+ * @param {function(devtools.profiler.ProfileView)} newProfileCallback Callback
+ * that receives a new processed profile.
+ * @constructor
+ */
+devtools.profiler.Processor = function()
+{
+ var dispatches = {
+ "code-creation": {
+ parsers: [null, this.createAddressParser("code"), parseInt, null],
+ processor: this.processCodeCreation_, backrefs: true,
+ needsProfile: true },
+ "code-move": { parsers: [this.createAddressParser("code"),
+ this.createAddressParser("code-move-to")],
+ processor: this.processCodeMove_, backrefs: true,
+ needsProfile: true },
+ "code-delete": { parsers: [this.createAddressParser("code")],
+ processor: this.processCodeDelete_, backrefs: true,
+ needsProfile: true },
+ "function-creation": { parsers: [this.createAddressParser("code"),
+ this.createAddressParser("function-obj")],
+ processor: this.processFunctionCreation_, backrefs: true },
+ "function-move": { parsers: [this.createAddressParser("code"),
+ this.createAddressParser("code-move-to")],
+ processor: this.processFunctionMove_, backrefs: true },
+ "function-delete": { parsers: [this.createAddressParser("code")],
+ processor: this.processFunctionDelete_, backrefs: true },
+ "tick": { parsers: [this.createAddressParser("code"),
+ this.createAddressParser("stack"), parseInt, "var-args"],
+ processor: this.processTick_, backrefs: true, needProfile: true },
+ "profiler": { parsers: [null, "var-args"],
+ processor: this.processProfiler_, needsProfile: false },
+ "heap-sample-begin": { parsers: [null, null, parseInt],
+ processor: this.processHeapSampleBegin_ },
+ "heap-sample-stats": { parsers: [null, null, parseInt, parseInt],
+ processor: this.processHeapSampleStats_ },
+ "heap-sample-item": { parsers: [null, parseInt, parseInt],
+ processor: this.processHeapSampleItem_ },
+ "heap-js-cons-item": { parsers: [null, parseInt, parseInt],
+ processor: this.processHeapJsConsItem_ },
+ "heap-js-ret-item": { parsers: [null, "var-args"],
+ processor: this.processHeapJsRetItem_ },
+ "heap-sample-end": { parsers: [null, null],
+ processor: this.processHeapSampleEnd_ },
+ // Not used in DevTools Profiler.
+ "shared-library": null,
+ // Obsolete row types.
+ "code-allocate": null,
+ "begin-code-region": null,
+ "end-code-region": null};
+
+ if (devtools.profiler.Profile.VERSION === 2) {
+ dispatches["tick"] = { parsers: [this.createAddressParser("code"),
+ this.createAddressParser("stack"),
+ this.createAddressParser("func"), parseInt, "var-args"],
+ processor: this.processTickV2_, backrefs: true };
+ }
+
+ devtools.profiler.LogReader.call(this, dispatches);
+
+ /**
+ * Callback that is called when a new profile is encountered in the log.
+ * @type {function()}
+ */
+ this.startedProfileProcessing_ = null;
+
+ /**
+ * Callback that is called periodically to display processing status.
+ * @type {function()}
+ */
+ this.profileProcessingStatus_ = null;
+
+ /**
+ * Callback that is called when a profile has been processed and is ready
+ * to be shown.
+ * @type {function(devtools.profiler.ProfileView)}
+ */
+ this.finishedProfileProcessing_ = null;
+
+ /**
+ * The current profile.
+ * @type {devtools.profiler.JsProfile}
+ */
+ this.currentProfile_ = null;
+
+ /**
+ * Builder of profile views. Created during "profiler,begin" event processing.
+ * @type {devtools.profiler.WebKitViewBuilder}
+ */
+ this.viewBuilder_ = null;
+
+ /**
+ * Next profile id.
+ * @type {number}
+ */
+ this.profileId_ = 1;
+
+ /**
+ * Counter for processed ticks.
+ * @type {number}
+ */
+ this.ticksCount_ = 0;
+
+ /**
+ * Interval id for updating processing status.
+ * @type {number}
+ */
+ this.processingInterval_ = null;
+
+ /**
+ * The current heap snapshot.
+ * @type {string}
+ */
+ this.currentHeapSnapshot_ = null;
+
+ /**
+ * Next heap snapshot id.
+ * @type {number}
+ */
+ this.heapSnapshotId_ = 1;
+};
+devtools.profiler.Processor.prototype.__proto__ = devtools.profiler.LogReader.prototype;
+
+
+/**
+ * @override
+ */
+devtools.profiler.Processor.prototype.printError = function(str)
+{
+ debugPrint(str);
+};
+
+
+/**
+ * @override
+ */
+devtools.profiler.Processor.prototype.skipDispatch = function(dispatch)
+{
+ return dispatch.needsProfile && this.currentProfile_ === null;
+};
+
+
+/**
+ * Sets profile processing callbacks.
+ *
+ * @param {function()} started Started processing callback.
+ * @param {function(devtools.profiler.ProfileView)} finished Finished
+ * processing callback.
+ */
+devtools.profiler.Processor.prototype.setCallbacks = function(started, processing, finished)
+{
+ this.startedProfileProcessing_ = started;
+ this.profileProcessingStatus_ = processing;
+ this.finishedProfileProcessing_ = finished;
+};
+
+
+/**
+ * An address for the fake "(program)" entry. WebKit's visualisation
+ * has assumptions on how the top of the call tree should look like,
+ * and we need to add a fake entry as the topmost function. This
+ * address is chosen because it's the end address of the first memory
+ * page, which is never used for code or data, but only as a guard
+ * page for catching AV errors.
+ *
+ * @type {number}
+ */
+devtools.profiler.Processor.PROGRAM_ENTRY = 0xffff;
+/**
+ * @type {string}
+ */
+devtools.profiler.Processor.PROGRAM_ENTRY_STR = "0xffff";
+
+
+/**
+ * Sets new profile callback.
+ * @param {function(devtools.profiler.ProfileView)} callback Callback function.
+ */
+devtools.profiler.Processor.prototype.setNewProfileCallback = function(callback)
+{
+ this.newProfileCallback_ = callback;
+};
+
+
+devtools.profiler.Processor.prototype.processProfiler_ = function(state, params)
+{
+ switch (state) {
+ case "resume":
+ if (this.currentProfile_ === null) {
+ this.currentProfile_ = new devtools.profiler.JsProfile();
+ // see the comment for devtools.profiler.Processor.PROGRAM_ENTRY
+ this.currentProfile_.addCode("Function", "(program)", devtools.profiler.Processor.PROGRAM_ENTRY, 1);
+ if (this.startedProfileProcessing_)
+ this.startedProfileProcessing_();
+ this.ticksCount_ = 0;
+ var self = this;
+ if (this.profileProcessingStatus_) {
+ this.processingInterval_ = window.setInterval(
+ function() { self.profileProcessingStatus_(self.ticksCount_); },
+ 1000);
+ }
+ }
+ break;
+ case "pause":
+ if (this.currentProfile_ !== null) {
+ window.clearInterval(this.processingInterval_);
+ this.processingInterval_ = null;
+ if (this.finishedProfileProcessing_)
+ this.finishedProfileProcessing_(this.createProfileForView());
+ this.currentProfile_ = null;
+ }
+ break;
+ case "begin":
+ var samplingRate = NaN;
+ if (params.length > 0)
+ samplingRate = parseInt(params[0]);
+ if (isNaN(samplingRate))
+ samplingRate = 1;
+ this.viewBuilder_ = new devtools.profiler.WebKitViewBuilder(samplingRate);
+ break;
+ // These events are valid but aren't used.
+ case "compression":
+ case "end": break;
+ default:
+ throw new Error("unknown profiler state: " + state);
+ }
+};
+
+
+devtools.profiler.Processor.prototype.processCodeCreation_ = function(type, start, size, name)
+{
+ this.currentProfile_.addCode(this.expandAlias(type), name, start, size);
+};
+
+
+devtools.profiler.Processor.prototype.processCodeMove_ = function(from, to)
+{
+ this.currentProfile_.moveCode(from, to);
+};
+
+
+devtools.profiler.Processor.prototype.processCodeDelete_ = function(start)
+{
+ this.currentProfile_.deleteCode(start);
+};
+
+
+devtools.profiler.Processor.prototype.processFunctionCreation_ = function(functionAddr, codeAddr)
+{
+ this.currentProfile_.addCodeAlias(functionAddr, codeAddr);
+};
+
+
+devtools.profiler.Processor.prototype.processFunctionMove_ = function(from, to)
+{
+ this.currentProfile_.safeMoveDynamicCode(from, to);
+};
+
+
+devtools.profiler.Processor.prototype.processFunctionDelete_ = function(start)
+{
+ this.currentProfile_.safeDeleteDynamicCode(start);
+};
+
+
+// TODO(mnaganov): Remove after next V8 roll.
+devtools.profiler.Processor.prototype.processTick_ = function(pc, sp, vmState, stack)
+{
+ // see the comment for devtools.profiler.Processor.PROGRAM_ENTRY
+ stack.push(devtools.profiler.Processor.PROGRAM_ENTRY_STR);
+ this.currentProfile_.recordTick(this.processStack(pc, stack));
+ this.ticksCount_++;
+};
+
+
+devtools.profiler.Processor.prototype.processTickV2_ = function(pc, sp, func, vmState, stack)
+{
+ // see the comment for devtools.profiler.Processor.PROGRAM_ENTRY
+ stack.push(devtools.profiler.Processor.PROGRAM_ENTRY_STR);
+
+
+ if (func) {
+ var funcEntry = this.currentProfile_.findEntry(func);
+ if (!funcEntry || !funcEntry.isJSFunction || !funcEntry.isJSFunction())
+ func = 0;
+ else {
+ var currEntry = this.currentProfile_.findEntry(pc);
+ if (!currEntry || !currEntry.isJSFunction || currEntry.isJSFunction()) {
+ func = 0;
+ }
+ }
+ }
+
+ this.currentProfile_.recordTick(this.processStack(pc, func, stack));
+ this.ticksCount_++;
+};
+
+
+devtools.profiler.Processor.prototype.processHeapSampleBegin_ = function(space, state, ticks)
+{
+ if (space !== "Heap") return;
+ this.currentHeapSnapshot_ = {
+ number: this.heapSnapshotId_++,
+ entries: {},
+ clusters: {},
+ lowlevels: {},
+ ticks: ticks
+ };
+};
+
+
+devtools.profiler.Processor.prototype.processHeapSampleStats_ = function(space, state, capacity, used)
+{
+ if (space !== "Heap") return;
+};
+
+
+devtools.profiler.Processor.prototype.processHeapSampleItem_ = function(item, number, size)
+{
+ if (!this.currentHeapSnapshot_) return;
+ this.currentHeapSnapshot_.lowlevels[item] = {
+ type: item, count: number, size: size
+ };
+};
+
+
+devtools.profiler.Processor.prototype.processHeapJsConsItem_ = function(item, number, size)
+{
+ if (!this.currentHeapSnapshot_) return;
+ this.currentHeapSnapshot_.entries[item] = {
+ cons: item, count: number, size: size, retainers: {}
+ };
+};
+
+
+devtools.profiler.Processor.prototype.processHeapJsRetItem_ = function(item, retainersArray)
+{
+ if (!this.currentHeapSnapshot_) return;
+ var rawRetainers = {};
+ for (var i = 0, n = retainersArray.length; i < n; ++i) {
+ var entry = retainersArray[i].split(";");
+ rawRetainers[entry[0]] = parseInt(entry[1], 10);
+ }
+
+ function mergeRetainers(entry) {
+ for (var rawRetainer in rawRetainers) {
+ var consName = rawRetainer.indexOf(":") !== -1 ? rawRetainer.split(":")[0] : rawRetainer;
+ if (!(consName in entry.retainers))
+ entry.retainers[consName] = { cons: consName, count: 0, clusters: {} };
+ var retainer = entry.retainers[consName];
+ retainer.count += rawRetainers[rawRetainer];
+ if (consName !== rawRetainer)
+ retainer.clusters[rawRetainer] = true;
+ }
+ }
+
+ if (item.indexOf(":") !== -1) {
+ // Array, Function, or Object instances cluster case.
+ if (!(item in this.currentHeapSnapshot_.clusters)) {
+ this.currentHeapSnapshot_.clusters[item] = {
+ cons: item, retainers: {}
+ };
+ }
+ mergeRetainers(this.currentHeapSnapshot_.clusters[item]);
+ item = item.split(":")[0];
+ }
+ mergeRetainers(this.currentHeapSnapshot_.entries[item]);
+};
+
+
+devtools.profiler.Processor.prototype.processHeapSampleEnd_ = function(space, state)
+{
+ if (space !== "Heap") return;
+ var snapshot = this.currentHeapSnapshot_;
+ this.currentHeapSnapshot_ = null;
+ WebInspector.panels.profiles.addSnapshot(snapshot);
+};
+
+
+/**
+ * Creates a profile for further displaying in ProfileView.
+ */
+devtools.profiler.Processor.prototype.createProfileForView = function()
+{
+ var profile = this.viewBuilder_.buildView(this.currentProfile_.getTopDownProfile());
+ profile.uid = this.profileId_++;
+ profile.title = UserInitiatedProfileName + "." + profile.uid;
+ return profile;
+};
diff --git a/WebKit/chromium/src/js/Tests.js b/WebKit/chromium/src/js/Tests.js
new file mode 100644
index 0000000..fa0c99f
--- /dev/null
+++ b/WebKit/chromium/src/js/Tests.js
@@ -0,0 +1,1862 @@
+/*
+ * 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;
+ };
+};
+
+
+// UI Tests
+
+
+/**
+ * Tests that the real injected host is present in the context.
+ */
+TestSuite.prototype.testHostIsPresent = function()
+{
+ this.assertTrue(typeof InspectorFrontendHost === "object" && !InspectorFrontendHost.isStub);
+};
+
+
+/**
+ * Tests elements tree has an "HTML" root.
+ */
+TestSuite.prototype.testElementsTreeRoot = function()
+{
+ var doc = WebInspector.domAgent.document;
+ this.assertEquals("HTML", doc.documentElement.nodeName);
+ this.assertTrue(doc.documentElement.hasChildNodes());
+};
+
+
+/**
+ * Tests that main resource is present in the system and that it is
+ * the only resource.
+ */
+TestSuite.prototype.testMainResource = function()
+{
+ var tokens = [];
+ var resources = WebInspector.resources;
+ for (var id in resources)
+ tokens.push(resources[id].lastPathComponent);
+ this.assertEquals("simple_page.html", tokens.join(","));
+};
+
+
+/**
+ * Tests that resources tab is enabled when corresponding item is selected.
+ */
+TestSuite.prototype.testEnableResourcesTab = function()
+{
+ this.showPanel("resources");
+
+ var test = this;
+ this.addSniffer(WebInspector, "updateResource",
+ function(identifier, payload) {
+ test.assertEquals("simple_page.html", payload.lastPathComponent);
+ WebInspector.panels.resources.refresh();
+ WebInspector.panels.resources.revealAndSelectItem(WebInspector.resources[identifier]);
+
+ test.releaseControl();
+ });
+
+ // Following call should lead to reload that we capture in the
+ // addResource override.
+ WebInspector.panels.resources._enableResourceTracking();
+
+ // We now have some time to report results to controller.
+ this.takeControl();
+};
+
+
+/**
+ * Tests that correct content length is reported for resources.
+ */
+TestSuite.prototype.testResourceContentLength = function()
+{
+ this.showPanel("resources");
+ var test = this;
+
+ var png = false;
+ var html = false;
+ this.addSniffer(WebInspector, "updateResource",
+ function(identifier, payload) {
+ if (!payload.didLengthChange)
+ return;
+ var resource = WebInspector.resources[identifier];
+ if (!resource || !resource.url)
+ return;
+ if (resource.url.search("image.html$") !== -1) {
+ var expectedLength = 87;
+ test.assertTrue(
+ resource.contentLength <= expectedLength,
+ "image.html content length is greater thatn expected.");
+ if (expectedLength === resource.contentLength)
+ html = true;
+ } else if (resource.url.search("image.png") !== -1) {
+ var expectedLength = 257796;
+ test.assertTrue(
+ resource.contentLength <= expectedLength,
+ "image.png content length is greater than expected.");
+ if (expectedLength === resource.contentLength)
+ png = true;
+ }
+ if (html && png) {
+ // Wait 1 second before releasing control to check that the content
+ // lengths are not updated anymore.
+ setTimeout(function() {
+ test.releaseControl();
+ }, 1000);
+ }
+ }, true);
+
+ // Make sure resource tracking is on.
+ WebInspector.panels.resources._enableResourceTracking();
+ // Reload inspected page to update all resources.
+ test.evaluateInConsole_(
+ "window.location.reload(true);",
+ function(resultText) {
+ test.assertEquals("undefined", resultText, "Unexpected result of reload().");
+ });
+
+ // We now have some time to report results to controller.
+ this.takeControl();
+};
+
+
+/**
+ * Tests resource headers.
+ */
+TestSuite.prototype.testResourceHeaders = function()
+{
+ this.showPanel("resources");
+
+ var test = this;
+
+ var responseOk = false;
+ var timingOk = false;
+
+ this.addSniffer(WebInspector, "updateResource",
+ function(identifier, payload) {
+ var resource = this.resources[identifier];
+ if (!resource || resource.mainResource) {
+ // We are only interested in secondary resources in this test.
+ return;
+ }
+
+ var requestHeaders = JSON.stringify(resource.requestHeaders);
+ test.assertContains(requestHeaders, "Accept");
+
+ if (payload.didResponseChange) {
+ var responseHeaders = JSON.stringify(resource.responseHeaders);
+ test.assertContains(responseHeaders, "Content-type");
+ test.assertContains(responseHeaders, "Content-Length");
+ test.assertTrue(typeof resource.responseReceivedTime !== "undefined");
+ responseOk = true;
+ }
+
+ if (payload.didTimingChange) {
+ test.assertTrue(typeof resource.startTime !== "undefined");
+ timingOk = true;
+ }
+
+ if (payload.didCompletionChange) {
+ test.assertTrue(responseOk);
+ test.assertTrue(timingOk);
+ test.assertTrue(typeof resource.endTime !== "undefined");
+ test.releaseControl();
+ }
+ }, true);
+
+ WebInspector.panels.resources._enableResourceTracking();
+ this.takeControl();
+};
+
+
+/**
+ * Tests the mime type of a cached (HTTP 304) resource.
+ */
+TestSuite.prototype.testCachedResourceMimeType = function()
+{
+ this.showPanel("resources");
+
+ var test = this;
+ var hasReloaded = false;
+
+ this.addSniffer(WebInspector, "updateResource",
+ function(identifier, payload) {
+ var resource = this.resources[identifier];
+ if (!resource || resource.mainResource) {
+ // We are only interested in secondary resources in this test.
+ return;
+ }
+
+ if (payload.didResponseChange) {
+ // Test server uses a default mime type for JavaScript files.
+ test.assertEquals("text/html", payload.mimeType);
+ if (!hasReloaded) {
+ hasReloaded = true;
+ // Reload inspected page to update all resources.
+ test.evaluateInConsole_("window.location.reload(true);", function() {});
+ } else
+ test.releaseControl();
+ }
+
+ }, true);
+
+ WebInspector.panels.resources._enableResourceTracking();
+ this.takeControl();
+};
+
+
+/**
+ * Tests that profiler works.
+ */
+TestSuite.prototype.testProfilerTab = function()
+{
+ this.showPanel("profiles");
+
+ var test = this;
+ this.addSniffer(WebInspector.panels.profiles, "addProfileHeader",
+ function(typeOrProfile, profile) {
+ if (!profile)
+ profile = typeOrProfile;
+ var panel = WebInspector.panels.profiles;
+ panel.showProfile(profile);
+ var node = panel.visibleView.profileDataGridTree.children[0];
+ // Iterate over displayed functions and search for a function
+ // that is called "fib" or "eternal_fib". If found, it 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();
+ });
+ var ticksCount = 0;
+ var tickRecord = "\nt,";
+ this.addSniffer(RemoteProfilerAgent, "didGetLogLines",
+ function(posIgnored, log) {
+ var pos = 0;
+ while ((pos = log.indexOf(tickRecord, pos)) !== -1) {
+ pos += tickRecord.length;
+ ticksCount++;
+ }
+ if (ticksCount > 100)
+ InspectorBackend.stopProfiling();
+ }, true);
+
+ InspectorBackend.startProfiling();
+ 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(devtools.DebuggerAgent.prototype, "reset", waitUntilScriptIsParsed);
+
+ // Reload inspected page. It will reset the debugger agent.
+ test.evaluateInConsole_(
+ "window.location.reload(true);",
+ function(resultText) {
+ test.assertEquals("undefined", resultText, "Unexpected result of reload().");
+ });
+
+ function waitUntilScriptIsParsed() {
+ var parsed = devtools.tools.getDebuggerAgent().parsedScripts_;
+ for (var id in parsed) {
+ var url = parsed[id].getUrl();
+ if (url && url.search("debugger_test_page.html$") !== -1) {
+ checkScriptsPanel();
+ return;
+ }
+ }
+ test.addSniffer(devtools.DebuggerAgent.prototype, "addScriptInfo_", waitUntilScriptIsParsed);
+ }
+
+ function checkScriptsPanel() {
+ test.showPanel("scripts");
+ test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html$"]), "Inspected script not found in the scripts list");
+ 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 a breakpoint can be set.
+ */
+TestSuite.prototype.testSetBreakpoint = function()
+{
+ var test = this;
+ this.showPanel("scripts");
+
+ var breakpointLine = 12;
+
+ this._waitUntilScriptsAreParsed(["debugger_test_page.html"],
+ function() {
+ test.showMainPageScriptSource_(
+ "debugger_test_page.html",
+ function(view, url) {
+ view._addBreakpoint(breakpointLine);
+ // Force v8 execution.
+ RemoteDebuggerAgent.processDebugCommands();
+ test.waitForSetBreakpointResponse_(url, breakpointLine,
+ function() {
+ test.releaseControl();
+ });
+ });
+ });
+
+ this.takeControl();
+};
+
+
+/**
+ * Tests that pause on exception works.
+ */
+TestSuite.prototype.testPauseOnException = function()
+{
+ this.showPanel("scripts");
+ var test = this;
+
+ // TODO(yurys): remove else branch once the states are supported.
+ if (WebInspector.ScriptsPanel.PauseOnExceptionsState) {
+ while (WebInspector.currentPanel.pauseOnExceptionButton.state !== WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions)
+ WebInspector.currentPanel.pauseOnExceptionButton.element.click();
+ } else {
+ // Make sure pause on exceptions is on.
+ if (!WebInspector.currentPanel.pauseOnExceptionButton.toggled)
+ WebInspector.currentPanel.pauseOnExceptionButton.element.click();
+ }
+
+ this._executeCodeWhenScriptsAreParsed("handleClick()", ["pause_on_exception.html$"]);
+
+ this._waitForScriptPause(
+ {
+ functionsOnStack: ["throwAnException", "handleClick", "(anonymous function)"],
+ lineNumber: 6,
+ lineText: " return unknown_var;"
+ },
+ function() {
+ test.releaseControl();
+ });
+
+ 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", "(anonymous function)"],
+ 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.console.visible = true;
+ WebInspector.console.prompt.text = code;
+ WebInspector.console.promptElement.dispatchEvent( TestSuite.createKeyEvent("Enter"));
+
+ this.addSniffer(WebInspector.ConsoleView.prototype, "addMessage",
+ function(commandResult) {
+ callback(commandResult.toMessageElement().textContent);
+ });
+};
+
+
+/*
+ * Waits for "setbreakpoint" response, checks that corresponding breakpoint
+ * was successfully set and invokes the callback if it was.
+ * @param {string} scriptUrl
+ * @param {number} breakpointLine
+ * @param {function()} callback
+ */
+TestSuite.prototype.waitForSetBreakpointResponse_ = function(scriptUrl, breakpointLine, callback)
+{
+ var test = this;
+ test.addSniffer(
+ devtools.DebuggerAgent.prototype,
+ "handleSetBreakpointResponse_",
+ function(msg) {
+ var bps = this.urlToBreakpoints_[scriptUrl];
+ test.assertTrue(!!bps, "No breakpoints for line " + breakpointLine);
+ var line = devtools.DebuggerAgent.webkitToV8LineNumber_(breakpointLine);
+ test.assertTrue(!!bps[line].getV8Id(), "Breakpoint id was not assigned.");
+ callback();
+ });
+};
+
+
+/**
+ * Tests eval on call frame.
+ */
+TestSuite.prototype.testEvalOnCallFrame = function()
+{
+ this.showPanel("scripts");
+
+ var breakpointLine = 16;
+
+ var test = this;
+ this.addSniffer(devtools.DebuggerAgent.prototype, "handleScriptsResponse_",
+ function(msg) {
+ test.showMainPageScriptSource_(
+ "debugger_test_page.html",
+ function(view, url) {
+ view._addBreakpoint(breakpointLine);
+ // Force v8 execution.
+ RemoteDebuggerAgent.processDebugCommands();
+ test.waitForSetBreakpointResponse_(url, breakpointLine, setBreakpointCallback);
+ });
+ });
+
+ function setBreakpointCallback() {
+ // Since breakpoints are ignored in evals' calculate() function is
+ // execute after zero-timeout so that the breakpoint is hit.
+ test.evaluateInConsole_(
+ 'setTimeout("calculate(123)" , 0)',
+ function(resultText) {
+ test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText);
+ waitForBreakpointHit();
+ });
+ }
+
+ function waitForBreakpointHit() {
+ test.addSniffer(
+ devtools.DebuggerAgent.prototype,
+ "handleBacktraceResponse_",
+ function(msg) {
+ test.assertEquals(2, this.callFrames_.length, "Unexpected stack depth on the breakpoint. " + JSON.stringify(msg));
+ test.assertEquals("calculate", this.callFrames_[0].functionName, "Unexpected top frame function.");
+ // Evaluate "e+1" where "e" is an argument of "calculate" function.
+ test.evaluateInConsole_(
+ "e+1",
+ function(resultText) {
+ test.assertEquals("124", resultText, 'Unexpected "e+1" value.');
+ test.releaseControl();
+ });
+ });
+ }
+
+ this.takeControl();
+};
+
+
+/**
+ * Tests that console auto completion works when script execution is paused.
+ */
+TestSuite.prototype.testCompletionOnPause = function()
+{
+ this.showPanel("scripts");
+ var test = this;
+ this._executeCodeWhenScriptsAreParsed("handleClick()", ["completion_on_pause.html$"]);
+
+ this._waitForScriptPause(
+ {
+ functionsOnStack: ["innerFunction", "handleClick", "(anonymous function)"],
+ lineNumber: 9,
+ lineText: " debugger;"
+ },
+ showConsole);
+
+ function showConsole() {
+ test.addSniffer(WebInspector.console, "afterShow", testLocalsCompletion);
+ WebInspector.showConsole();
+ }
+
+ function testLocalsCompletion() {
+ checkCompletions("th", ["parameter1", "closureLocal", "p", "createClosureLocal"], testThisCompletion);
+ }
+
+ function testThisCompletion() {
+ checkCompletions("this.", ["field1", "field2", "m"], testFieldCompletion);
+ }
+
+ function testFieldCompletion() {
+ checkCompletions("this.field1.", ["id", "name"], function() { test.releaseControl(); });
+ }
+
+ function checkCompletions(expression, expectedProperties, callback) {
+ test.addSniffer(WebInspector.console, "_reportCompletions",
+ function(bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix, result, isException) {
+ test.assertTrue(!isException, "Exception while collecting completions");
+ for (var i = 0; i < expectedProperties.length; i++) {
+ var name = expectedProperties[i];
+ test.assertTrue(result[name], "Name " + name + " not found among the completions: " + JSON.stringify(result));
+ }
+ setTimeout(callback, 0);
+ });
+ WebInspector.console.prompt.text = expression;
+ WebInspector.console.prompt.autoCompleteSoon();
+ }
+
+ this.takeControl();
+};
+
+
+/**
+ * Tests that inspected page doesn't hang on reload if it contains a syntax
+ * error and DevTools window is open.
+ */
+TestSuite.prototype.testAutoContinueOnSyntaxError = function()
+{
+ this.showPanel("scripts");
+ var test = this;
+
+ function checkScriptsList() {
+ var scriptSelect = document.getElementById("scripts-files");
+ var options = scriptSelect.options;
+ // There should be only console API source (see
+ // InjectedScript._ensureCommandLineAPIInstalled) since the page script
+ // contains a syntax error.
+ for (var i = 0 ; i < options.length; i++) {
+ if (options[i].text.search("script_syntax_error.html$") !== -1)
+ test.fail("Script with syntax error should not be in the list of parsed scripts.");
+ }
+ }
+
+ this.addSniffer(devtools.DebuggerAgent.prototype, "handleScriptsResponse_",
+ function(msg) {
+ checkScriptsList();
+
+ // Reload inspected page.
+ test.evaluateInConsole_(
+ "window.location.reload(true);",
+ function(resultText) {
+ test.assertEquals("undefined", resultText, "Unexpected result of reload().");
+ waitForExceptionEvent();
+ });
+ });
+
+ function waitForExceptionEvent() {
+ var exceptionCount = 0;
+ test.addSniffer(
+ devtools.DebuggerAgent.prototype,
+ "handleExceptionEvent_",
+ function(msg) {
+ exceptionCount++;
+ test.assertEquals(1, exceptionCount, "Too many exceptions.");
+ test.assertEquals(undefined, msg.getBody().script, "Unexpected exception: " + JSON.stringify(msg));
+ test.releaseControl();
+ });
+
+ // Check that the script is not paused on parse error.
+ test.addSniffer(
+ WebInspector,
+ "pausedScript",
+ function(callFrames) {
+ test.fail("Script execution should not pause on syntax error.");
+ });
+ }
+
+ this.takeControl();
+};
+
+
+/**
+ * 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,
+ "pausedScript",
+ function(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();
+ }
+};
+
+
+/**
+ * Performs sequence of steps.
+ * @param {Array.<Object|Function>} Array [expectations1,action1,expectations2,
+ * action2,...,actionN].
+ */
+TestSuite.prototype._performSteps = function(actions)
+{
+ var test = this;
+ var i = 0;
+ function doNextAction() {
+ if (i > 0)
+ actions[i++]();
+ if (i < actions.length - 1)
+ test._waitForScriptPause(actions[i++], doNextAction);
+ }
+ doNextAction();
+};
+
+
+/**
+ * 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);
+ });
+ }
+
+ 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, "parsedScriptSource", waitForAllScripts);
+ }
+
+ waitForAllScripts();
+};
+
+
+/**
+ * Waits until all debugger scripts are parsed and executes "a()" in the
+ * inspected page.
+ */
+TestSuite.prototype._executeFunctionForStepTest = function()
+{
+ this._executeCodeWhenScriptsAreParsed("a()", ["debugger_step.html$", "debugger_step.js$"]);
+};
+
+
+/**
+ * Tests step over in the debugger.
+ */
+TestSuite.prototype.testStepOver = function()
+{
+ this.showPanel("scripts");
+ var test = this;
+
+ this._executeFunctionForStepTest();
+
+ this._performSteps([
+ {
+ functionsOnStack: ["d","a","(anonymous function)"],
+ lineNumber: 3,
+ lineText: " debugger;"
+ },
+ function() {
+ document.getElementById("scripts-step-over").click();
+ },
+ {
+ functionsOnStack: ["d","a","(anonymous function)"],
+ lineNumber: 5,
+ lineText: " var y = fact(10);"
+ },
+ function() {
+ document.getElementById("scripts-step-over").click();
+ },
+ {
+ functionsOnStack: ["d","a","(anonymous function)"],
+ lineNumber: 6,
+ lineText: " return y;"
+ },
+ function() {
+ test.releaseControl();
+ }
+ ]);
+
+ test.takeControl();
+};
+
+
+/**
+ * Tests step out in the debugger.
+ */
+TestSuite.prototype.testStepOut = function()
+{
+ this.showPanel("scripts");
+ var test = this;
+
+ this._executeFunctionForStepTest();
+
+ this._performSteps([
+ {
+ functionsOnStack: ["d","a","(anonymous function)"],
+ lineNumber: 3,
+ lineText: " debugger;"
+ },
+ function() {
+ document.getElementById("scripts-step-out").click();
+ },
+ {
+ functionsOnStack: ["a","(anonymous function)"],
+ lineNumber: 8,
+ lineText: " printResult(result);"
+ },
+ function() {
+ test.releaseControl();
+ }
+ ]);
+
+ test.takeControl();
+};
+
+
+/**
+ * Tests step in in the debugger.
+ */
+TestSuite.prototype.testStepIn = function()
+{
+ this.showPanel("scripts");
+ var test = this;
+
+ this._executeFunctionForStepTest();
+
+ this._performSteps([
+ {
+ functionsOnStack: ["d","a","(anonymous function)"],
+ lineNumber: 3,
+ lineText: " debugger;"
+ },
+ function() {
+ document.getElementById("scripts-step-over").click();
+ },
+ {
+ functionsOnStack: ["d","a","(anonymous function)"],
+ lineNumber: 5,
+ lineText: " var y = fact(10);"
+ },
+ function() {
+ document.getElementById("scripts-step-into").click();
+ },
+ {
+ functionsOnStack: ["fact","d","a","(anonymous function)"],
+ lineNumber: 15,
+ lineText: " return r;"
+ },
+ function() {
+ test.releaseControl();
+ }
+ ]);
+
+ test.takeControl();
+};
+
+
+/**
+ * Gets a XPathResult matching given xpath.
+ * @param {string} xpath
+ * @param {number} resultType
+ * @param {Node} opt_ancestor Context node. If not specified documentElement
+ * will be used
+ * @return {XPathResult} Type of returned value is determined by "resultType" parameter
+ */
+
+TestSuite.prototype._evaluateXpath = function(xpath, resultType, opt_ancestor)
+{
+ if (!opt_ancestor)
+ opt_ancestor = document.documentElement;
+ try {
+ return document.evaluate(xpath, opt_ancestor, null, resultType, null);
+ } catch(e) {
+ this.fail('Error in expression: "' + xpath + '".' + e);
+ }
+};
+
+
+/**
+ * Gets first Node matching given xpath.
+ * @param {string} xpath
+ * @param {Node} opt_ancestor Context node. If not specified documentElement
+ * will be used
+ * @return {?Node}
+ */
+TestSuite.prototype._findNode = function(xpath, opt_ancestor)
+{
+ var result = this._evaluateXpath(xpath, XPathResult.FIRST_ORDERED_NODE_TYPE, opt_ancestor).singleNodeValue;
+ this.assertTrue(!!result, "Cannot find node on path: " + xpath);
+ return result;
+};
+
+
+/**
+ * Gets a text matching given xpath.
+ * @param {string} xpath
+ * @param {Node} opt_ancestor Context node. If not specified documentElement
+ * will be used
+ * @return {?string}
+ */
+TestSuite.prototype._findText = function(xpath, opt_ancestor)
+{
+ var result = this._evaluateXpath(xpath, XPathResult.STRING_TYPE, opt_ancestor).stringValue;
+ this.assertTrue(!!result, "Cannot find text on path: " + xpath);
+ return result;
+};
+
+
+/**
+ * Gets an iterator over nodes matching given xpath.
+ * @param {string} xpath
+ * @param {Node} opt_ancestor Context node. If not specified, documentElement
+ * will be used
+ * @return {XPathResult} Iterator over the nodes
+ */
+TestSuite.prototype._nodeIterator = function(xpath, opt_ancestor)
+{
+ return this._evaluateXpath(xpath, XPathResult.ORDERED_NODE_ITERATOR_TYPE, opt_ancestor);
+};
+
+
+/**
+ * Checks the scopeSectionDiv against the expectations.
+ * @param {Node} scopeSectionDiv The section div
+ * @param {Object} expectations Expectations dictionary
+ */
+TestSuite.prototype._checkScopeSectionDiv = function(scopeSectionDiv, expectations)
+{
+ var scopeTitle = this._findText('./div[@class="header"]/div[@class="title"]/text()', scopeSectionDiv);
+ this.assertEquals(expectations.title, scopeTitle, "Unexpected scope section title.");
+ if (!expectations.properties)
+ return;
+ this.assertTrue(scopeSectionDiv.hasStyleClass("expanded"), 'Section "' + scopeTitle + '" is collapsed.');
+
+ var propertyIt = this._nodeIterator("./ol/li", scopeSectionDiv);
+ var propertyLi;
+ var foundProps = [];
+ while (propertyLi = propertyIt.iterateNext()) {
+ var name = this._findText('./span[@class="name"]/text()', propertyLi);
+ var value = this._findText('./span[@class="value"]/text()', propertyLi);
+ this.assertTrue(!!name, 'Invalid variable name: "' + name + '"');
+ this.assertTrue(name in expectations.properties, "Unexpected property: " + name);
+ this.assertEquals(expectations.properties[name], value, 'Unexpected "' + name + '" property value.');
+ delete expectations.properties[name];
+ foundProps.push(name + " = " + value);
+ }
+
+ // Check that all expected properties were found.
+ for (var p in expectations.properties)
+ this.fail('Property "' + p + '" was not found in scope "' + scopeTitle + '". Found properties: "' + foundProps.join(",") + '"');
+};
+
+
+/**
+ * Expands scope sections matching the filter and invokes the callback on
+ * success.
+ * @param {function(WebInspector.ObjectPropertiesSection, number):boolean}
+ * filter
+ * @param {Function} callback
+ */
+TestSuite.prototype._expandScopeSections = function(filter, callback)
+{
+ var sections = WebInspector.currentPanel.sidebarPanes.scopechain.sections;
+
+ var toBeUpdatedCount = 0;
+ function updateListener() {
+ --toBeUpdatedCount;
+ if (toBeUpdatedCount === 0) {
+ // Report when all scopes are expanded and populated.
+ callback();
+ }
+ }
+
+ // Global scope is always the last one.
+ for (var i = 0; i < sections.length - 1; i++) {
+ var section = sections[i];
+ if (!filter(sections, i))
+ continue;
+ ++toBeUpdatedCount;
+ var populated = section.populated;
+
+ this._hookGetPropertiesCallback(updateListener,
+ function() {
+ section.expand();
+ if (populated) {
+ // Make sure "updateProperties" callback will be called at least once
+ // after it was overridden.
+ section.update();
+ }
+ });
+ }
+};
+
+
+/**
+ * Tests that scopes can be expanded and contain expected data.
+ */
+TestSuite.prototype.testExpandScope = function()
+{
+ this.showPanel("scripts");
+ var test = this;
+
+ this._executeCodeWhenScriptsAreParsed("handleClick()", ["debugger_closure.html$"]);
+
+ this._waitForScriptPause(
+ {
+ functionsOnStack: ["innerFunction", "handleClick", "(anonymous function)"],
+ lineNumber: 8,
+ lineText: " debugger;"
+ },
+ expandAllSectionsExceptGlobal);
+
+ // Expanding Global scope takes for too long so we skeep it.
+ function expandAllSectionsExceptGlobal() {
+ test._expandScopeSections(function(sections, i) {
+ return i < sections.length - 1;
+ },
+ examineScopes /* When all scopes are expanded and populated check them. */);
+ }
+
+ // Check scope sections contents.
+ function examineScopes() {
+ var scopeVariablesSection = test._findNode('//div[@id="scripts-sidebar"]/div[div[@class="title"]/text()="Scope Variables"]');
+ var expectedScopes = [
+ {
+ title: "Local",
+ properties: {
+ x:"2009",
+ innerFunctionLocalVar:"2011",
+ "this": "global",
+ }
+ },
+ {
+ title: "Closure",
+ properties: {
+ n:"TextParam",
+ makeClosureLocalVar:"local.TextParam",
+ }
+ },
+ {
+ title: "Global",
+ },
+ ];
+ var it = test._nodeIterator('./div[@class="body"]/div', scopeVariablesSection);
+ var scopeIndex = 0;
+ var scopeDiv;
+ while (scopeDiv = it.iterateNext()) {
+ test.assertTrue(scopeIndex < expectedScopes.length, "Too many scopes.");
+ test._checkScopeSectionDiv(scopeDiv, expectedScopes[scopeIndex]);
+ ++scopeIndex;
+ }
+ test.assertEquals(expectedScopes.length, scopeIndex, "Unexpected number of scopes.");
+
+ test.releaseControl();
+ }
+
+ test.takeControl();
+};
+
+
+/**
+ * Returns child tree element for a property with given name.
+ * @param {TreeElement} parent Parent tree element.
+ * @param {string} childName
+ * @param {string} objectPath Path to the object. Will be printed in the case
+ * of failure.
+ * @return {TreeElement}
+ */
+TestSuite.prototype._findChildProperty = function(parent, childName, objectPath)
+{
+ var children = parent.children;
+ for (var i = 0; i < children.length; i++) {
+ var treeElement = children[i];
+ var property = treeElement.property;
+ if (property.name === childName)
+ return treeElement;
+ }
+ this.fail('Cannot find property "' + childName + '" in ' + objectPath);
+};
+
+
+/**
+ * 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;
+ }
+};
+
+
+/**
+ * Tests that all elements in prototype chain of an object have expected
+ * intrinic proprties(__proto__, constructor, prototype).
+ */
+TestSuite.prototype.testDebugIntrinsicProperties = function()
+{
+ this.showPanel("scripts");
+ var test = this;
+
+ this._executeCodeWhenScriptsAreParsed("handleClick()", ["debugger_intrinsic_properties.html$"]);
+
+ this._waitForScriptPause(
+ {
+ functionsOnStack: ["callDebugger", "handleClick", "(anonymous function)"],
+ lineNumber: 29,
+ lineText: " debugger;"
+ },
+ expandLocalScope);
+
+ var localScopeSection = null;
+ function expandLocalScope() {
+ test._expandScopeSections(function(sections, i) {
+ if (i === 0) {
+ test.assertTrue(sections[i].object.isLocal, "Scope #0 is not Local.");
+ localScopeSection = sections[i];
+ return true;
+ }
+ return false;
+ },
+ examineLocalScope);
+ }
+
+ function examineLocalScope() {
+ var scopeExpectations = [
+ "a", "Object", [
+ "constructor", "function Child()", [
+ "constructor", "function Function()", null,
+ "name", "Child", null,
+ "prototype", "Object", [
+ "childProtoField", 21, null
+ ]
+ ],
+
+ "__proto__", "Object", [
+ "__proto__", "Object", [
+ "__proto__", "Object", [
+ "__proto__", "null", null,
+ "constructor", "function Object()", null,
+ ],
+ "constructor", "function Parent()", [
+ "name", "Parent", null,
+ "prototype", "Object", [
+ "parentProtoField", 11, null,
+ ]
+ ],
+ "parentProtoField", 11, null,
+ ],
+ "constructor", "function Child()", null,
+ "childProtoField", 21, null,
+ ],
+
+ "parentField", 10, null,
+ "childField", 20, null,
+ ]
+ ];
+
+ checkProperty(localScopeSection.propertiesTreeOutline, "<Local Scope>", scopeExpectations);
+ }
+
+ var propQueue = [];
+ var index = 0;
+ var expectedFinalIndex = 8;
+
+ function expandAndCheckNextProperty() {
+ if (index === propQueue.length) {
+ test.assertEquals(expectedFinalIndex, index, "Unexpected number of expanded objects.");
+ test.releaseControl();
+ return;
+ }
+
+ // Read next property data from the queue.
+ var treeElement = propQueue[index].treeElement;
+ var path = propQueue[index].path;
+ var expectations = propQueue[index].expectations;
+ index++;
+
+ // Expand the property.
+ test._hookGetPropertiesCallback(function() {
+ checkProperty(treeElement, path, expectations);
+ },
+ function() {
+ treeElement.expand();
+ });
+ }
+
+ function checkProperty(treeElement, path, expectations) {
+ for (var i = 0; i < expectations.length; i += 3) {
+ var name = expectations[i];
+ var description = expectations[i+1];
+ var value = expectations[i+2];
+
+ var propertyPath = path + "." + name;
+ var propertyTreeElement = test._findChildProperty(treeElement, name, path);
+ test.assertTrue(propertyTreeElement, 'Property "' + propertyPath + '" not found.');
+ test.assertEquals(description, propertyTreeElement.property.value.description, 'Unexpected "' + propertyPath + '" description.');
+ if (value) {
+ // Schedule property content check.
+ propQueue.push({
+ treeElement: propertyTreeElement,
+ path: propertyPath,
+ expectations: value,
+ });
+ }
+ }
+ // Check next property in the queue.
+ expandAndCheckNextProperty();
+ }
+
+ test.takeControl();
+};
+
+
+/**
+ * Tests "Pause" button will pause debugger when a snippet is evaluated.
+ */
+TestSuite.prototype.testPauseInEval = function()
+{
+ this.showPanel("scripts");
+
+ var test = this;
+
+ var pauseButton = document.getElementById("scripts-pause");
+ pauseButton.click();
+
+ devtools.tools.evaluateJavaScript("fib(10)");
+
+ this.addSniffer(WebInspector, "pausedScript",
+ function() {
+ test.releaseControl();
+ });
+
+ test.takeControl();
+};
+
+
+/**
+ * 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;
+};
+
+
+/**
+ * Tests console eval.
+ */
+TestSuite.prototype.testConsoleEval = function()
+{
+ var test = this;
+ this.evaluateInConsole_("123",
+ function(resultText) {
+ test.assertEquals("123", resultText);
+ test.releaseControl();
+ });
+
+ this.takeControl();
+};
+
+
+/**
+ * Tests console log.
+ */
+TestSuite.prototype.testConsoleLog = function()
+{
+ WebInspector.console.visible = true;
+ var messages = WebInspector.console.messages;
+ var index = 0;
+
+ var test = this;
+ var assertNext = function(line, message, opt_class, opt_count, opt_substr) {
+ var elem = messages[index++].toMessageElement();
+ var clazz = elem.getAttribute("class");
+ var expectation = (opt_count || '') + 'console_test_page.html:' + line + message;
+ if (opt_substr)
+ test.assertContains(elem.textContent, expectation);
+ else
+ test.assertEquals(expectation, elem.textContent);
+ if (opt_class)
+ test.assertContains(clazz, "console-" + opt_class);
+ };
+
+ assertNext("5", "log", "log-level");
+ assertNext("7", "debug", "log-level");
+ assertNext("9", "info", "log-level");
+ assertNext("11", "warn", "warning-level");
+ assertNext("13", "error", "error-level");
+ assertNext("15", "Message format number 1, 2 and 3.5");
+ assertNext("17", "Message format for string");
+ assertNext("19", "Object Object");
+ assertNext("22", "repeated", "log-level", 5);
+ assertNext("26", "count: 1");
+ assertNext("26", "count: 2");
+ assertNext("29", "group", "group-title");
+ index++;
+ assertNext("33", "timer:", "log-level", "", true);
+ assertNext("35", "1 2 3", "log-level");
+ assertNext("37", "HTMLDocument", "log-level");
+ assertNext("39", "<html>", "log-level", "", true);
+};
+
+
+/**
+ * Tests eval of global objects.
+ */
+TestSuite.prototype.testEvalGlobal = function()
+{
+ WebInspector.console.visible = true;
+
+ var inputs = ["foo", "foobar"];
+ var expectations = ["foo", "fooValue", "foobar", "ReferenceError: foobar is not defined"];
+
+ // Do not change code below - simply add inputs and expectations above.
+ var initEval = function(input) {
+ WebInspector.console.prompt.text = input;
+ WebInspector.console.promptElement.dispatchEvent( TestSuite.createKeyEvent("Enter"));
+ };
+ var test = this;
+ var messagesCount = 0;
+ var inputIndex = 0;
+ this.addSniffer(WebInspector.ConsoleView.prototype, "addMessage",
+ function(commandResult) {
+ messagesCount++;
+ if (messagesCount === expectations.length) {
+ var messages = WebInspector.console.messages;
+ for (var i = 0; i < expectations; ++i) {
+ var elem = messages[i++].toMessageElement();
+ test.assertEquals(elem.textContent, expectations[i]);
+ }
+ test.releaseControl();
+ } else if (messagesCount % 2 === 0)
+ initEval(inputs[inputIndex++]);
+ }, true);
+
+ initEval(inputs[inputIndex++]);
+ this.takeControl();
+};
+
+
+/**
+ * Tests that Storage panel can be open and that local DOM storage is added
+ * to the panel.
+ */
+TestSuite.prototype.testShowStoragePanel = function()
+{
+ var test = this;
+ this.addSniffer(WebInspector.panels.storage, "addDOMStorage",
+ function(storage) {
+ var orig = storage.getEntries;
+ storage.getEntries = function(callback) {
+ orig.call(this, function(entries) {
+ callback(entries);
+ test.releaseControl();
+ });
+ };
+ try {
+ WebInspector.currentPanel.selectDOMStorage(storage.id);
+ storage.getEntries = orig;
+ } catch (e) {
+ test.fail("Exception in selectDOMStorage: " + e);
+ }
+ });
+ this.showPanel("storage");
+
+ // Access localStorage so that it's pushed to the frontend.
+ this.evaluateInConsole_(
+ 'setTimeout("localStorage.x = 10" , 0)',
+ function(resultText) {
+ test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText);
+ });
+
+ // Wait until DOM storage is added to the panel.
+ this.takeControl();
+};
+
+
+/**
+ * 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)
+{
+ new TestSuite().runTest(name);
+};
+
+
+}
diff --git a/WebKit/chromium/src/js/devTools.css b/WebKit/chromium/src/js/devTools.css
new file mode 100755
index 0000000..1fa935f
--- /dev/null
+++ b/WebKit/chromium/src/js/devTools.css
@@ -0,0 +1,223 @@
+#scripts-files option.injected {
+ color: rgb(70, 134, 240);
+}
+
+.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 {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(242, 247, 253)), to(rgb(223, 234, 248)));
+}
+
+body.platform-windows.inactive #toolbar {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(248, 248, 248)), to(rgb(237, 237, 237)));
+}
+
+
+/* Heap Profiler Styles */
+
+.heap-snapshot-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/focusButtonGlyph.png);
+}
+
+.heap-snapshot-sidebar-tree-item .icon {
+ content: url(Images/profileIcon.png);
+}
+
+.heap-snapshot-sidebar-tree-item.small .icon {
+ content: url(Images/profileSmallIcon.png);
+}
+
+.heap-snapshot-view {
+ display: none;
+ overflow: hidden;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+}
+
+.heap-snapshot-view.visible {
+ display: block;
+}
+
+.heap-snapshot-view .data-grid {
+ border: none;
+ max-height: 100%;
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 93px;
+}
+
+.heap-snapshot-view .data-grid th.count-column {
+ text-align: center;
+}
+
+.heap-snapshot-view .data-grid td.count-column {
+ text-align: right;
+}
+
+.heap-snapshot-view .data-grid th.size-column {
+ text-align: center;
+}
+
+.heap-snapshot-view .data-grid td.size-column {
+ text-align: right;
+}
+
+.heap-snapshot-view .data-grid th.countDelta-column {
+ text-align: center;
+}
+
+.heap-snapshot-view .data-grid td.countDelta-column {
+ text-align: right;
+}
+
+.heap-snapshot-view .data-grid th.sizeDelta-column {
+ text-align: center;
+}
+
+.heap-snapshot-view .data-grid td.sizeDelta-column {
+ text-align: right;
+}
+
+#heap-snapshot-summary-container {
+ position: absolute;
+ padding-top: 20px;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 93px;
+ margin-left: -1px;
+ border-left: 1px solid rgb(102, 102, 102);
+ background-color: rgb(101, 111, 130);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));
+ background-repeat: repeat-x;
+ background-position: top;
+ text-align: center;
+ text-shadow: black 0 1px 1px;
+ white-space: nowrap;
+ color: white;
+ -webkit-background-size: 1px 6px;
+ -webkit-background-origin: padding;
+ -webkit-background-clip: padding;
+}
+
+.heap-snapshot-summary {
+ display: inline-block;
+ width: 50%;
+ min-width: 300px;
+ position: relative;
+}
+
+.heap-snapshot-summary canvas.summary-graph {
+ width: 225px;
+}
+
+.heap-snapshot-summary-label {
+ font-size: 12px;
+ font-weight: bold;
+ position: absolute;
+ top: 1px;
+ width: 50%;
+ left: 25%;
+}
+
+body.platform-windows .section > .header {
+ border: 1px solid rgb(92, 116, 157);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(105, 133, 180)), to(rgb(92, 116, 157)));
+}
+
+body.platform-windows .console-group-messages .section > .header {
+ padding: 0 8px 0 0;
+ background-image: none;
+ border: none;
+ min-height: 0;
+}
+
+body.platform-windows #resources-filter {
+ background: -webkit-gradient(linear, left top, left bottom, from(rgb(233, 233, 233)), to(rgb(233, 233, 233)));
+}
+
+body.platform-windows .crumbs .crumb {
+ -webkit-border-image: url(Images/segmentChromium.png) 0 12 0 2;
+}
+
+body.platform-windows .crumbs .crumb.end {
+ -webkit-border-image: url(Images/segmentEndChromium.png) 0 2 0 2;
+}
+
+body.platform-windows .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;
+}
+
+body.platform-windows .crumbs .crumb.selected:hover {
+ -webkit-border-image: url(Images/segmentSelectedChromium.png) 0 12 0 2;
+}
+
+body.platform-windows .crumbs .crumb.selected.end, .crumbs .crumb.selected.end:hover {
+ -webkit-border-image: url(Images/segmentSelectedEndChromium.png) 0 2 0 2;
+}
+
+body.platform-windows .crumbs .crumb:hover {
+ -webkit-border-image: url(Images/segmentHoverChromium.png) 0 12 0 2;
+}
+
+body.platform-windows .crumbs .crumb.dimmed:hover {
+ -webkit-border-image: url(Images/segmentHoverChromium.png) 0 12 0 2;
+}
+
+body.platform-windows .crumbs .crumb.end:hover {
+ -webkit-border-image: url(Images/segmentHoverEndChromium.png) 0 2 0 2;
+}
+
+body.platform-windows body.drawer-visible #main-status-bar {
+ background-image: url(Images/statusbarResizerVertical.png), url(Images/statusbarBackgroundChromium.png);
+}
+
+body.platform-windows .status-bar {
+ background-image: url(Images/statusbarBackgroundChromium.png);
+}
+
+body.platform-windows button.status-bar-item {
+ background-image: url(Images/statusbarButtonsChromium.png);
+}
+
+body.platform-windows select.status-bar-item:active {
+ -webkit-border-image: url(Images/statusbarMenuButtonSelectedChromium.png) 0 17 0 2;
+}
+
+body.platform-windows #drawer {
+ background-image: url(Images/statusbarBottomBackgroundChromium.png);
+}
+
+body.platform-windows 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-tree-item input {
+ vertical-align: middle;
+}
diff --git a/WebKit/chromium/tests/TransparencyWinTest.cpp b/WebKit/chromium/tests/TransparencyWinTest.cpp
new file mode 100644
index 0000000..b83c2a9
--- /dev/null
+++ b/WebKit/chromium/tests/TransparencyWinTest.cpp
@@ -0,0 +1,693 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "TransparencyWin.h"
+
+#include "AffineTransform.h"
+#include "ImageBuffer.h"
+
+#include <gtest/gtest.h>
+#include <windows.h>
+
+namespace WebCore {
+
+static FloatRect RECTToFloatRect(const RECT* rect)
+{
+ return FloatRect(static_cast<float>(rect->left),
+ static_cast<float>(rect->top),
+ static_cast<float>(rect->right - rect->left),
+ static_cast<float>(rect->bottom - rect->top));
+}
+
+static void drawNativeRect(GraphicsContext* context,
+ int x, int y, int w, int h)
+{
+ skia::PlatformCanvas* canvas = context->platformContext()->canvas();
+ HDC dc = canvas->beginPlatformPaint();
+
+ RECT innerRc;
+ innerRc.left = x;
+ innerRc.top = y;
+ innerRc.right = x + w;
+ innerRc.bottom = y + h;
+ FillRect(dc, &innerRc,
+ reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
+
+ canvas->endPlatformPaint();
+}
+
+static Color getPixelAt(GraphicsContext* context, int x, int y)
+{
+ const SkBitmap& bitmap = context->platformContext()->canvas()->
+ getTopPlatformDevice().accessBitmap(false);
+ return Color(*reinterpret_cast<const RGBA32*>(bitmap.getAddr32(x, y)));
+}
+
+// Resets the top layer's alpha channel to 0 for each pixel. This simulates
+// Windows messing it up.
+static void clearTopLayerAlphaChannel(GraphicsContext* context)
+{
+ SkBitmap& bitmap = const_cast<SkBitmap&>(context->platformContext()->
+ canvas()->getTopPlatformDevice().accessBitmap(false));
+ for (int y = 0; y < bitmap.height(); y++) {
+ uint32_t* row = bitmap.getAddr32(0, y);
+ for (int x = 0; x < bitmap.width(); x++)
+ row[x] &= 0x00FFFFFF;
+ }
+}
+
+// Clears the alpha channel on the specified pixel.
+static void clearTopLayerAlphaPixel(GraphicsContext* context, int x, int y)
+{
+ SkBitmap& bitmap = const_cast<SkBitmap&>(context->platformContext()->
+ canvas()->getTopPlatformDevice().accessBitmap(false));
+ *bitmap.getAddr32(x, y) &= 0x00FFFFFF;
+}
+
+static std::ostream& operator<<(std::ostream& out, const Color& c)
+{
+ std::ios_base::fmtflags oldFlags = out.flags(std::ios_base::hex |
+ std::ios_base::showbase);
+ out << c.rgb();
+ out.flags(oldFlags);
+ return out;
+}
+
+TEST(TransparencyWin, NoLayer)
+{
+ OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(17, 16), DeviceRGB));
+
+ // KeepTransform
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::NoLayer,
+ TransparencyWin::KeepTransform,
+ IntRect(1, 1, 14, 12));
+
+ EXPECT_TRUE(src->context() == helper.context());
+ EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize);
+ EXPECT_TRUE(IntRect(1, 1, 14, 12) == helper.drawRect());
+ }
+
+ // Untransform is not allowed for NoLayer.
+
+ // ScaleTransform
+ src->context()->save();
+ src->context()->scale(FloatSize(2.0, 0.5));
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::NoLayer,
+ TransparencyWin::ScaleTransform,
+ IntRect(2, 2, 6, 6));
+ helper.composite();
+
+ // The coordinate system should be based in the upper left of our box.
+ // It should be post-transformed.
+ EXPECT_TRUE(src->context() == helper.context());
+ EXPECT_TRUE(IntSize(12, 3) == helper.m_layerSize);
+ EXPECT_TRUE(IntRect(4, 1, 12, 3) == helper.drawRect());
+ }
+ src->context()->restore();
+}
+
+TEST(TransparencyWin, WhiteLayer)
+{
+ OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), DeviceRGB));
+
+ // KeepTransform
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::WhiteLayer,
+ TransparencyWin::KeepTransform,
+ IntRect(1, 1, 14, 12));
+ helper.composite();
+
+ EXPECT_TRUE(src->context() != helper.context());
+ EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize);
+ EXPECT_TRUE(IntRect(1, 1, 14, 12) == helper.drawRect());
+ }
+
+ // Untransform
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::WhiteLayer,
+ TransparencyWin::Untransform,
+ IntRect(1, 1, 14, 12));
+ helper.composite();
+
+ EXPECT_TRUE(src->context() != helper.context());
+ EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize);
+ EXPECT_TRUE(IntRect(0, 0, 14, 12) == helper.drawRect());
+ }
+
+ // ScaleTransform
+ src->context()->save();
+ src->context()->scale(FloatSize(2.0, 0.5));
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::WhiteLayer,
+ TransparencyWin::ScaleTransform,
+ IntRect(2, 2, 6, 6));
+ helper.composite();
+
+ // The coordinate system should be based in the upper left of our box.
+ // It should be post-transformed.
+ EXPECT_TRUE(src->context() != helper.context());
+ EXPECT_TRUE(IntSize(12, 3) == helper.m_layerSize);
+ EXPECT_TRUE(IntRect(0, 0, 12, 3) == helper.drawRect());
+ }
+ src->context()->restore();
+}
+
+TEST(TransparencyWin, TextComposite)
+{
+ OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), DeviceRGB));
+
+ // KeepTransform is the only valid transform mode for TextComposite.
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::TextComposite,
+ TransparencyWin::KeepTransform,
+ IntRect(1, 1, 14, 12));
+ helper.composite();
+
+ EXPECT_TRUE(src->context() != helper.context());
+ EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize);
+ EXPECT_TRUE(IntRect(1, 1, 14, 12) == helper.drawRect());
+ }
+}
+
+TEST(TransparencyWin, OpaqueCompositeLayer)
+{
+ OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), DeviceRGB));
+
+ // KeepTransform
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::OpaqueCompositeLayer,
+ TransparencyWin::KeepTransform,
+ IntRect(1, 1, 14, 12));
+ helper.composite();
+
+ EXPECT_TRUE(src->context() != helper.context());
+ EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize);
+ EXPECT_TRUE(IntRect(1, 1, 14, 12) == helper.drawRect());
+ }
+
+ // KeepTransform with scroll applied.
+ src->context()->save();
+ src->context()->translate(0, -1);
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::OpaqueCompositeLayer,
+ TransparencyWin::KeepTransform,
+ IntRect(1, 1, 14, 14));
+ helper.composite();
+
+ EXPECT_TRUE(src->context() != helper.context());
+ EXPECT_TRUE(IntSize(14, 14) == helper.m_layerSize);
+ EXPECT_TRUE(IntRect(1, 1, 14, 14) == helper.drawRect());
+ }
+ src->context()->restore();
+
+ // Untransform
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::OpaqueCompositeLayer,
+ TransparencyWin::Untransform,
+ IntRect(1, 1, 14, 12));
+ helper.composite();
+
+ EXPECT_TRUE(src->context() != helper.context());
+ EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize);
+ EXPECT_TRUE(IntRect(0, 0, 14, 12) == helper.drawRect());
+ }
+
+ // ScaleTransform
+ src->context()->save();
+ src->context()->scale(FloatSize(2.0, 0.5));
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::OpaqueCompositeLayer,
+ TransparencyWin::ScaleTransform,
+ IntRect(2, 2, 6, 6));
+ helper.composite();
+
+ // The coordinate system should be based in the upper left of our box.
+ // It should be post-transformed.
+ EXPECT_TRUE(src->context() != helper.context());
+ EXPECT_TRUE(IntSize(12, 3) == helper.m_layerSize);
+ EXPECT_TRUE(IntRect(0, 0, 12, 3) == helper.drawRect());
+ }
+ src->context()->restore();
+}
+
+TEST(TransparencyWin, WhiteLayerPixelTest)
+{
+ // Make a total transparent buffer, and draw the white layer inset by 1 px.
+ OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), DeviceRGB));
+
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::WhiteLayer,
+ TransparencyWin::KeepTransform,
+ IntRect(1, 1, 14, 14));
+
+ // Coordinates should be in the original space, not the layer.
+ drawNativeRect(helper.context(), 3, 3, 1, 1);
+ clearTopLayerAlphaChannel(helper.context());
+ helper.composite();
+ }
+
+ // The final image should be transparent around the edges for 1 px, white
+ // in the middle, with (3,3) (what we drew above) being opaque black.
+ EXPECT_EQ(Color(Color::transparent), getPixelAt(src->context(), 0, 0));
+ EXPECT_EQ(Color(Color::white), getPixelAt(src->context(), 2, 2));
+ EXPECT_EQ(Color(Color::black), getPixelAt(src->context(), 3, 3));
+ EXPECT_EQ(Color(Color::white), getPixelAt(src->context(), 4, 4));
+}
+
+TEST(TransparencyWin, OpaqueCompositeLayerPixel)
+{
+ Color red(0xFFFF0000), darkRed(0xFFBF0000);
+ Color green(0xFF00FF00);
+
+ // Make a red bottom layer, followed by a half green next layer @ 50%.
+ OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), DeviceRGB));
+
+ FloatRect fullRect(0, 0, 16, 16);
+ src->context()->fillRect(fullRect, red, DeviceColorSpace);
+ src->context()->beginTransparencyLayer(0.5);
+ FloatRect rightHalf(8, 0, 8, 16);
+ src->context()->fillRect(rightHalf, green, DeviceColorSpace);
+
+ // Make a transparency layer inset by one pixel, and fill it inset by
+ // another pixel with 50% black.
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::OpaqueCompositeLayer,
+ TransparencyWin::KeepTransform,
+ IntRect(1, 1, 14, 14));
+
+ FloatRect inner(2, 2, 12, 12);
+ helper.context()->fillRect(inner, Color(0x7f000000), DeviceColorSpace);
+ // These coordinates are relative to the layer, whish is inset by 1x1
+ // pixels from the top left. So we're actually clearing (2, 2) and
+ // (13,13), which are the extreme corners of the black area (and which
+ // we check below).
+ clearTopLayerAlphaPixel(helper.context(), 1, 1);
+ clearTopLayerAlphaPixel(helper.context(), 12, 12);
+ helper.composite();
+ }
+
+ // Finish the compositing.
+ src->context()->endTransparencyLayer();
+
+ // Check that we got the right values, it should be like the rectangle was
+ // drawn with half opacity even though the alpha channel got messed up.
+ EXPECT_EQ(red, getPixelAt(src->context(), 0, 0));
+ EXPECT_EQ(red, getPixelAt(src->context(), 1, 1));
+ EXPECT_EQ(darkRed, getPixelAt(src->context(), 2, 2));
+
+ // The dark result is:
+ // (black @ 50% atop green) @ 50% atop red = 0xFF804000
+ // which is 0xFFA02000 (Skia computes 0xFFA11F00 due to rounding).
+ Color darkGreenRed(0xFF803f00);
+ EXPECT_EQ(darkGreenRed, getPixelAt(src->context(), 13, 13));
+
+ // 50% green on top of red = FF808000 (rounded to what Skia will produce).
+ Color greenRed(0xFF807F00);
+ EXPECT_EQ(greenRed, getPixelAt(src->context(), 14, 14));
+ EXPECT_EQ(greenRed, getPixelAt(src->context(), 15, 15));
+}
+
+// Tests that translations are properly handled when using KeepTransform.
+TEST(TransparencyWin, TranslateOpaqueCompositeLayer)
+{
+ // Fill with white.
+ OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), DeviceRGB));
+ Color white(0xFFFFFFFF);
+ FloatRect fullRect(0, 0, 16, 16);
+ src->context()->fillRect(fullRect, white, DeviceColorSpace);
+
+ // Scroll down by 8 (coordinate system goes up).
+ src->context()->save();
+ src->context()->translate(0, -8);
+
+ Color red(0xFFFF0000);
+ Color green(0xFF00FF00);
+ {
+ // Make the transparency layer after translation will be @ (0, -8) with
+ // size 16x16.
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::OpaqueCompositeLayer,
+ TransparencyWin::KeepTransform,
+ IntRect(0, 0, 16, 16));
+
+ // Draw a red pixel at (15, 15). This should be the at (15, 7) after
+ // the transform.
+ FloatRect bottomRight(15, 15, 1, 1);
+ helper.context()->fillRect(bottomRight, green, DeviceColorSpace);
+ helper.composite();
+ }
+
+ src->context()->restore();
+
+ // Check the pixel we wrote.
+ EXPECT_EQ(green, getPixelAt(src->context(), 15, 7));
+}
+
+// Same as OpaqueCompositeLayer, but the canvas has a rotation applied. This
+// tests that the propert transform is applied to the copied layer.
+TEST(TransparencyWin, RotateOpaqueCompositeLayer)
+{
+ OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), DeviceRGB));
+
+ // The background is white.
+ Color white(0xFFFFFFFF);
+ FloatRect fullRect(0, 0, 16, 16);
+ src->context()->fillRect(fullRect, white, DeviceColorSpace);
+
+ // Rotate the image by 90 degrees. This matrix is the same as
+ // cw90.rotate(90); but avoids rounding errors. Rounding errors can cause
+ // Skia to think that !rectStaysRect() and it will fall through to path
+ // drawing mode, which in turn gives us antialiasing. We want no
+ // antialiasing or other rounding problems since we're testing exact pixel
+ // values.
+ src->context()->save();
+ AffineTransform cw90(0, 1, -1, 0, 0, 0);
+ src->context()->concatCTM(cw90);
+
+ // Make a transparency layer consisting of a horizontal line of 50% black.
+ // Since the rotation is applied, this will actually be a vertical line
+ // down the middle of the image.
+ src->context()->beginTransparencyLayer(0.5);
+ FloatRect blackRect(0, -9, 16, 2);
+ Color black(0xFF000000);
+ src->context()->fillRect(blackRect, black, DeviceColorSpace);
+
+ // Now draw 50% red square.
+ {
+ // Create a transparency helper inset one pixel in the buffer. The
+ // coordinates are before transforming into this space, and maps to
+ // IntRect(1, 1, 14, 14).
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::OpaqueCompositeLayer,
+ TransparencyWin::Untransform,
+ IntRect(1, -15, 14, 14));
+
+ // Fill with red.
+ helper.context()->fillRect(helper.drawRect(), Color(0x7f7f0000), DeviceColorSpace);
+ clearTopLayerAlphaChannel(helper.context());
+ helper.composite();
+ }
+
+ // Finish the compositing.
+ src->context()->endTransparencyLayer();
+
+ // Top corner should be the original background.
+ EXPECT_EQ(white, getPixelAt(src->context(), 0, 0));
+
+ // Check the stripe down the middle, first at the top...
+ Color gray(0xFF808080);
+ EXPECT_EQ(white, getPixelAt(src->context(), 6, 0));
+ EXPECT_EQ(gray, getPixelAt(src->context(), 7, 0));
+ EXPECT_EQ(gray, getPixelAt(src->context(), 8, 0));
+ EXPECT_EQ(white, getPixelAt(src->context(), 9, 0));
+
+ // ...now at the bottom.
+ EXPECT_EQ(white, getPixelAt(src->context(), 6, 15));
+ EXPECT_EQ(gray, getPixelAt(src->context(), 7, 15));
+ EXPECT_EQ(gray, getPixelAt(src->context(), 8, 15));
+ EXPECT_EQ(white, getPixelAt(src->context(), 9, 15));
+
+ // Our red square should be 25% red over the top of those two.
+ Color redwhite(0xFFdfbfbf);
+ Color redgray(0xFF9f8080);
+ EXPECT_EQ(white, getPixelAt(src->context(), 0, 1));
+ EXPECT_EQ(redwhite, getPixelAt(src->context(), 1, 1));
+ EXPECT_EQ(redwhite, getPixelAt(src->context(), 6, 1));
+ EXPECT_EQ(redgray, getPixelAt(src->context(), 7, 1));
+ EXPECT_EQ(redgray, getPixelAt(src->context(), 8, 1));
+ EXPECT_EQ(redwhite, getPixelAt(src->context(), 9, 1));
+ EXPECT_EQ(redwhite, getPixelAt(src->context(), 14, 1));
+ EXPECT_EQ(white, getPixelAt(src->context(), 15, 1));
+
+ // Complete the 50% transparent layer.
+ src->context()->restore();
+}
+
+TEST(TransparencyWin, TranslateScaleOpaqueCompositeLayer)
+{
+ OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), DeviceRGB));
+
+ // The background is white on top with red on bottom.
+ Color white(0xFFFFFFFF);
+ FloatRect topRect(0, 0, 16, 8);
+ src->context()->fillRect(topRect, white, DeviceColorSpace);
+ Color red(0xFFFF0000);
+ FloatRect bottomRect(0, 8, 16, 8);
+ src->context()->fillRect(bottomRect, red, DeviceColorSpace);
+
+ src->context()->save();
+
+ // Translate left by one pixel.
+ AffineTransform left;
+ left.translate(-1, 0);
+
+ // Scale by 2x.
+ AffineTransform scale;
+ scale.scale(2.0);
+ src->context()->concatCTM(scale);
+
+ // Then translate up by one pixel (which will actually be 2 due to scaling).
+ AffineTransform up;
+ up.translate(0, -1);
+ src->context()->concatCTM(up);
+
+ // Now draw 50% red square.
+ {
+ // Create a transparency helper inset one pixel in the buffer. The
+ // coordinates are before transforming into this space, and maps to
+ // IntRect(1, 1, 14, 14).
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::OpaqueCompositeLayer,
+ TransparencyWin::KeepTransform,
+ IntRect(1, -15, 14, 14));
+
+ // Fill with red.
+ helper.context()->fillRect(helper.drawRect(), Color(0x7f7f0000), DeviceColorSpace);
+ clearTopLayerAlphaChannel(helper.context());
+ helper.composite();
+ }
+}
+
+// Tests scale mode with no additional copy.
+TEST(TransparencyWin, Scale)
+{
+ // Create an opaque white buffer.
+ OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), DeviceRGB));
+ FloatRect fullBuffer(0, 0, 16, 16);
+ src->context()->fillRect(fullBuffer, Color::white, DeviceColorSpace);
+
+ // Scale by 2x.
+ src->context()->save();
+ AffineTransform scale;
+ scale.scale(2.0);
+ src->context()->concatCTM(scale);
+
+ // Start drawing a rectangle from 1->4. This should get scaled to 2->8.
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::NoLayer,
+ TransparencyWin::ScaleTransform,
+ IntRect(1, 1, 3, 3));
+
+ // The context should now have the identity transform and the returned
+ // rect should be scaled.
+ EXPECT_TRUE(helper.context()->getCTM().isIdentity());
+ EXPECT_EQ(2, helper.drawRect().x());
+ EXPECT_EQ(2, helper.drawRect().y());
+ EXPECT_EQ(8, helper.drawRect().right());
+ EXPECT_EQ(8, helper.drawRect().bottom());
+
+ // Set the pixel at (2, 2) to be transparent. This should be fixed when
+ // the helper goes out of scope. We don't want to call
+ // clearTopLayerAlphaChannel because that will actually clear the whole
+ // canvas (since we have no extra layer!).
+ SkBitmap& bitmap = const_cast<SkBitmap&>(helper.context()->
+ platformContext()->canvas()->getTopPlatformDevice().
+ accessBitmap(false));
+ *bitmap.getAddr32(2, 2) &= 0x00FFFFFF;
+ helper.composite();
+ }
+
+ src->context()->restore();
+
+ // Check the pixel we previously made transparent, it should have gotten
+ // fixed back up to white.
+
+ // The current version doesn't fixup transparency when there is no layer.
+ // This seems not to be necessary, so we don't bother, but if it becomes
+ // necessary, this line should be uncommented.
+ // EXPECT_EQ(Color(Color::white), getPixelAt(src->context(), 2, 2));
+}
+
+// Tests scale mode with an additional copy for transparency. This will happen
+// if we have a scaled textbox, for example. WebKit will create a new
+// transparency layer, draw the text field, then draw the text into it, then
+// composite this down with an opacity.
+TEST(TransparencyWin, ScaleTransparency)
+{
+ // Create an opaque white buffer.
+ OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), DeviceRGB));
+ FloatRect fullBuffer(0, 0, 16, 16);
+ src->context()->fillRect(fullBuffer, Color::white, DeviceColorSpace);
+
+ // Make another layer (which duplicates how WebKit will make this). We fill
+ // the top half with red, and have the layer be 50% opaque.
+ src->context()->beginTransparencyLayer(0.5);
+ FloatRect topHalf(0, 0, 16, 8);
+ src->context()->fillRect(topHalf, Color(0xFFFF0000), DeviceColorSpace);
+
+ // Scale by 2x.
+ src->context()->save();
+ AffineTransform scale;
+ scale.scale(2.0);
+ src->context()->concatCTM(scale);
+
+ // Make a layer inset two pixels (because of scaling, this is 2->14). And
+ // will it with 50% black.
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::OpaqueCompositeLayer,
+ TransparencyWin::ScaleTransform,
+ IntRect(1, 1, 6, 6));
+
+ helper.context()->fillRect(helper.drawRect(), Color(0x7f000000), DeviceColorSpace);
+ clearTopLayerAlphaChannel(helper.context());
+ helper.composite();
+ }
+
+ // Finish the layer.
+ src->context()->restore();
+ src->context()->endTransparencyLayer();
+
+ Color redBackground(0xFFFF8080); // 50% red composited on white.
+ EXPECT_EQ(redBackground, getPixelAt(src->context(), 0, 0));
+ EXPECT_EQ(redBackground, getPixelAt(src->context(), 1, 1));
+
+ // Top half (minus two pixel border) should be 50% gray atop opaque
+ // red = 0xFF804141. Then that's composited with 50% transparency on solid
+ // white = 0xFFC0A1A1.
+ Color darkRed(0xFFBF8080);
+ EXPECT_EQ(darkRed, getPixelAt(src->context(), 2, 2));
+ EXPECT_EQ(darkRed, getPixelAt(src->context(), 7, 7));
+
+ // Bottom half (minus a two pixel border) should be a layer with 5% gray
+ // with another 50% opacity composited atop white.
+ Color darkWhite(0xFFBFBFBF);
+ EXPECT_EQ(darkWhite, getPixelAt(src->context(), 8, 8));
+ EXPECT_EQ(darkWhite, getPixelAt(src->context(), 13, 13));
+
+ Color white(0xFFFFFFFF); // Background in the lower-right.
+ EXPECT_EQ(white, getPixelAt(src->context(), 14, 14));
+ EXPECT_EQ(white, getPixelAt(src->context(), 15, 15));
+}
+
+TEST(TransparencyWin, Text)
+{
+ OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), DeviceRGB));
+
+ // Our text should end up 50% transparent blue-green.
+ Color fullResult(0x80008080);
+
+ {
+ TransparencyWin helper;
+ helper.init(src->context(),
+ TransparencyWin::TextComposite,
+ TransparencyWin::KeepTransform,
+ IntRect(0, 0, 16, 16));
+ helper.setTextCompositeColor(fullResult);
+
+ // Write several different squares to simulate ClearType. These should
+ // all reduce to 2/3 coverage.
+ FloatRect pixel(0, 0, 1, 1);
+ helper.context()->fillRect(pixel, 0xFFFF0000, DeviceColorSpace);
+ pixel.move(1.0f, 0.0f);
+ helper.context()->fillRect(pixel, 0xFF00FF00, DeviceColorSpace);
+ pixel.move(1.0f, 0.0f);
+ helper.context()->fillRect(pixel, 0xFF0000FF, DeviceColorSpace);
+ pixel.move(1.0f, 0.0f);
+ helper.context()->fillRect(pixel, 0xFF008080, DeviceColorSpace);
+ pixel.move(1.0f, 0.0f);
+ helper.context()->fillRect(pixel, 0xFF800080, DeviceColorSpace);
+ pixel.move(1.0f, 0.0f);
+ helper.context()->fillRect(pixel, 0xFF808000, DeviceColorSpace);
+
+ // Try one with 100% coverage (opaque black).
+ pixel.move(1.0f, 0.0f);
+ helper.context()->fillRect(pixel, 0xFF000000, DeviceColorSpace);
+
+ // Now mess with the alpha channel.
+ clearTopLayerAlphaChannel(helper.context());
+ helper.composite();
+ }
+
+ Color oneThirdResult(0x55005555); // = fullResult * 2 / 3
+ EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 0, 0));
+ EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 1, 0));
+ EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 2, 0));
+ EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 3, 0));
+ EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 4, 0));
+ EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 5, 0));
+ EXPECT_EQ(fullResult, getPixelAt(src->context(), 6, 0));
+ EXPECT_EQ(Color::transparent, getPixelAt(src->context(), 7, 0));
+}
+
+} // namespace WebCore
diff --git a/WebKit/chromium/tests/UniscribeHelperTest.cpp b/WebKit/chromium/tests/UniscribeHelperTest.cpp
new file mode 100644
index 0000000..8aaed11
--- /dev/null
+++ b/WebKit/chromium/tests/UniscribeHelperTest.cpp
@@ -0,0 +1,165 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+
+#include <gtest/gtest.h>
+
+#include "PlatformString.h"
+#include "UniscribeHelper.h"
+
+using namespace WebCore;
+
+namespace {
+
+class UniscribeTest : public testing::Test {
+public:
+ UniscribeTest()
+ {
+ }
+
+ // Returns an HFONT with the given name. The caller does not have to free
+ // this, it will be automatically freed at the end of the test. Returns 0
+ // on failure. On success, the
+ HFONT MakeFont(const wchar_t* fontName, SCRIPT_CACHE** cache)
+ {
+ LOGFONT lf;
+ memset(&lf, 0, sizeof(LOGFONT));
+ lf.lfHeight = 20;
+ wcscpy_s(lf.lfFaceName, fontName);
+
+ HFONT hfont = CreateFontIndirect(&lf);
+ if (!hfont)
+ return 0;
+
+ *cache = new SCRIPT_CACHE;
+ **cache = 0;
+ createdFonts.append(std::make_pair(hfont, *cache));
+ return hfont;
+ }
+
+protected:
+ // Default font properties structure for tests to use.
+ SCRIPT_FONTPROPERTIES properties;
+
+private:
+ virtual void SetUp()
+ {
+ memset(&properties, 0, sizeof(SCRIPT_FONTPROPERTIES));
+ properties.cBytes = sizeof(SCRIPT_FONTPROPERTIES);
+ properties.wgBlank = ' ';
+ properties.wgDefault = '?'; // Used when the char is not in the font.
+ properties.wgInvalid = '#'; // Used for invalid characters.
+ }
+
+ virtual void TearDown()
+ {
+ // Free any allocated fonts.
+ for (size_t i = 0; i < createdFonts.size(); i++) {
+ DeleteObject(createdFonts[i].first);
+ ScriptFreeCache(createdFonts[i].second);
+ delete createdFonts[i].second;
+ }
+ createdFonts.clear();
+ }
+
+ // Tracks allocated fonts so we can delete them at the end of the test.
+ // The script cache pointer is heap allocated and must be freed.
+ Vector< std::pair<HFONT, SCRIPT_CACHE*> > createdFonts;
+};
+
+} // namespace
+
+// This test tests giving Uniscribe a very large buffer, which will cause a
+// failure.
+TEST_F(UniscribeTest, TooBig)
+{
+ // Make a large string with an e with a zillion combining accents.
+ String input(L"e");
+ for (int i = 0; i < 100000; i++)
+ input.append(static_cast<UChar>(0x301)); // Combining acute accent.
+
+ SCRIPT_CACHE* scriptCache;
+ HFONT hfont = MakeFont(L"Times New Roman", &scriptCache);
+ ASSERT_TRUE(hfont);
+
+ // Test a long string without the normal length protection we have. This
+ // will cause shaping to fail.
+ {
+ UniscribeHelper uniscribe(
+ input.characters(), static_cast<int>(input.length()),
+ false, hfont, scriptCache, &properties);
+ uniscribe.initWithOptionalLengthProtection(false);
+
+ // There should be one shaping entry, with nothing in it.
+ ASSERT_EQ(1, uniscribe.m_shapes.size());
+ EXPECT_EQ(0, uniscribe.m_shapes[0].m_glyphs.size());
+ EXPECT_EQ(0, uniscribe.m_shapes[0].m_logs.size());
+ EXPECT_EQ(0, uniscribe.m_shapes[0].m_visualAttributes.size());
+ EXPECT_EQ(0, uniscribe.m_shapes[0].m_advance.size());
+ EXPECT_EQ(0, uniscribe.m_shapes[0].m_offsets.size());
+ EXPECT_EQ(0, uniscribe.m_shapes[0].m_justify.size());
+ EXPECT_EQ(0, uniscribe.m_shapes[0].m_abc.abcA);
+ EXPECT_EQ(0, uniscribe.m_shapes[0].m_abc.abcB);
+ EXPECT_EQ(0, uniscribe.m_shapes[0].m_abc.abcC);
+
+ // The sizes of the other stuff should match the shaping entry.
+ EXPECT_EQ(1, uniscribe.m_runs.size());
+ EXPECT_EQ(1, uniscribe.m_screenOrder.size());
+
+ // Check that the various querying functions handle the empty case
+ // properly.
+ EXPECT_EQ(0, uniscribe.width());
+ EXPECT_EQ(0, uniscribe.firstGlyphForCharacter(0));
+ EXPECT_EQ(0, uniscribe.firstGlyphForCharacter(1000));
+ EXPECT_EQ(0, uniscribe.xToCharacter(0));
+ EXPECT_EQ(0, uniscribe.xToCharacter(1000));
+ }
+
+ // Now test the very large string and make sure it is handled properly by
+ // the length protection.
+ {
+ UniscribeHelper uniscribe(
+ input.characters(), static_cast<int>(input.length()),
+ false, hfont, scriptCache, &properties);
+ uniscribe.initWithOptionalLengthProtection(true);
+
+ // There should be 0 runs and shapes.
+ EXPECT_EQ(0, uniscribe.m_runs.size());
+ EXPECT_EQ(0, uniscribe.m_shapes.size());
+ EXPECT_EQ(0, uniscribe.m_screenOrder.size());
+
+ EXPECT_EQ(0, uniscribe.width());
+ EXPECT_EQ(0, uniscribe.firstGlyphForCharacter(0));
+ EXPECT_EQ(0, uniscribe.firstGlyphForCharacter(1000));
+ EXPECT_EQ(0, uniscribe.xToCharacter(0));
+ EXPECT_EQ(0, uniscribe.xToCharacter(1000));
+ }
+}
diff --git a/WebKit/gtk/ChangeLog b/WebKit/gtk/ChangeLog
index 92de7e4..7a44884 100644
--- a/WebKit/gtk/ChangeLog
+++ b/WebKit/gtk/ChangeLog
@@ -1,3 +1,97 @@
+2010-02-09 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] Hits assertion on history back, with page cache enabled, in specific conditions
+ https://bugs.webkit.org/show_bug.cgi?id=34773
+
+ Make sure cached frames have their scrollbars disconnected from
+ the WebView's adjustments.
+
+ * WebCoreSupport/FrameLoaderClientGtk.cpp:
+ (WebKit::FrameLoaderClient::savePlatformDataToCachedFrame):
+
+2010-02-09 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] Set GtkAdjustments on our FrameView when loading a page in the PageCache
+ https://bugs.webkit.org/show_bug.cgi?id=34754
+
+ Test that lower, and upper bounds are kept when goibg back with
+ page cache enabled, and disabled. Page cache behaviour is still a
+ bit broken (see FIXME).
+
+ * tests/testwebview.c:
+ (server_callback):
+ (map_event_cb):
+ (do_test_webkit_web_view_adjustments):
+ (test_webkit_web_view_adjustments):
+ (main):
+
+2010-02-09 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Gustavo Noronha.
+
+ [GTK] Set GtkAdjustments on our FrameView when loading a page in the PageCache
+ https://bugs.webkit.org/show_bug.cgi?id=34754
+
+ Set the Gtk Adjustments of the FrameViews when they are restored
+ from the PageCache too. Right we only do it for the newly created
+ FrameViews in transitionToCommittedForNewPage, but we it also
+ needs to be done in the equilavent transition method for cached
+ pages.
+
+ * WebCoreSupport/FrameLoaderClientGtk.cpp:
+ (WebKit::postCommitFrameViewSetup):
+ (WebKit::FrameLoaderClient::transitionToCommittedFromCachedFrame):
+ (WebKit::FrameLoaderClient::transitionToCommittedForNewPage):
+
+2010-02-08 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Gustavo Noronha.
+
+ [GTK] Implement FrameLoaderClient::hasWebView
+ https://bugs.webkit.org/show_bug.cgi?id=34682
+
+ Used for sanity-check ASSERTS in the FrameLoader code.
+
+ * WebCoreSupport/FrameLoaderClientGtk.cpp:
+ (WebKit::FrameLoaderClient::hasWebView):
+
+2010-02-08 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk>
+
+ Reviewed by Xan Lopez.
+
+ News about 1.1.21.
+
+ * NEWS:
+
+2010-02-05 Shinichiro Hamaji <hamaji@chromium.org>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [Gtk] Implement layoutTestController.pageNumberForElementById
+ https://bugs.webkit.org/show_bug.cgi?id=34572
+
+ * webkit/webkitprivate.h:
+ * webkit/webkitwebframe.cpp:
+ (webkit_web_frame_page_number_for_element_by_id):
+
+2010-02-04 Christian Dywan <christian@twotoasts.de>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GTK] Add and cleanup return values of signals in view and frame
+ https://bugs.webkit.org/show_bug.cgi?id=33484
+
+ Add missing and cleanup return values of web frame and web view signals.
+
+ * webkit/webkitwebframe.cpp:
+ (webkit_web_frame_class_init):
+ * webkit/webkitwebview.cpp:
+ (DNDContentsRequest::webkit_web_view_class_init):
+
2010-02-02 Gustavo Noronha Silva <gns@gnome.org>
Reviewed by Xan Lopez.
diff --git a/WebKit/gtk/NEWS b/WebKit/gtk/NEWS
index 807fca4..4e5bc2c 100644
--- a/WebKit/gtk/NEWS
+++ b/WebKit/gtk/NEWS
@@ -1,4 +1,18 @@
=================
+WebKitGTK+ 1.1.21
+=================
+
+What's new in WebKitGTK+ 1.1.21?
+
+ - New custom-made GStreamer source element that uses the WebCore
+ network layer to download media data; this makes sure any headers
+ and cookies will automatically get added when making requests.
+ - WebKit will now let libsoup know who the first party for a given
+ message is, making it possible to implement accept/deny policies in
+ Soup.
+ - The usual stream of fixes, and improvements
+
+=================
WebKitGTK+ 1.1.20
=================
diff --git a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp
index 8f1bec2..1ccc8a1 100644
--- a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp
+++ b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp
@@ -3,7 +3,7 @@
* Copyright (C) 2007, 2008, 2009 Holger Hans Peter Freyther
* Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
* Copyright (C) 2008, 2009 Collabora Ltd. All rights reserved.
- * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org>
+ * Copyright (C) 2009, 2010 Gustavo Noronha Silva <gns@gnome.org>
* Copyright (C) Research In Motion Limited 2009. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -25,6 +25,7 @@
#include "FrameLoaderClientGtk.h"
#include "ArchiveResource.h"
+#include "CachedFrame.h"
#include "Color.h"
#include "DocumentLoader.h"
#include "DocumentLoaderGtk.h"
@@ -563,8 +564,7 @@ void FrameLoaderClient::setMainFrameDocumentReady(bool)
bool FrameLoaderClient::hasWebView() const
{
- notImplemented();
- return true;
+ return getViewFromFrame(m_frame);
}
void FrameLoaderClient::dispatchDidFinishLoad()
@@ -646,9 +646,7 @@ void FrameLoaderClient::setCopiesOnScroll()
void FrameLoaderClient::detachedFromParent2()
{
- FrameView *view = core(m_frame)->view();
- if (view)
- view->setGtkAdjustments(0, 0);
+ notImplemented();
}
void FrameLoaderClient::detachedFromParent3()
@@ -1116,12 +1114,40 @@ void FrameLoaderClient::updateGlobalHistoryRedirectLinks()
notImplemented();
}
-void FrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame*)
+void FrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
+{
+ // We need to do this here in order to disconnect the scrollbars
+ // that are being used by the frame that is being cached from the
+ // adjustments, otherwise they will react to changes in the
+ // adjustments, and bad things will happen.
+ if (cachedFrame->view())
+ cachedFrame->view()->setGtkAdjustments(0, 0);
+}
+
+static void postCommitFrameViewSetup(WebKitWebFrame *frame, FrameView *view, bool resetValues)
{
+ WebKitWebView* containingWindow = getViewFromFrame(frame);
+ WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(containingWindow);
+ view->setGtkAdjustments(priv->horizontalAdjustment, priv->verticalAdjustment, resetValues);
+
+ if (priv->currentMenu) {
+ GtkMenu* menu = priv->currentMenu;
+ priv->currentMenu = 0;
+
+ gtk_menu_popdown(menu);
+ g_object_unref(menu);
+ }
}
-void FrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
+void FrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame* cachedFrame)
{
+ ASSERT(cachedFrame->view());
+
+ Frame* frame = core(m_frame);
+ if (frame != frame->page()->mainFrame())
+ return;
+
+ postCommitFrameViewSetup(m_frame, cachedFrame->view(), false);
}
void FrameLoaderClient::transitionToCommittedForNewPage()
@@ -1140,16 +1166,7 @@ void FrameLoaderClient::transitionToCommittedForNewPage()
if (frame != frame->page()->mainFrame())
return;
- WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(containingWindow);
- frame->view()->setGtkAdjustments(priv->horizontalAdjustment, priv->verticalAdjustment);
-
- if (priv->currentMenu) {
- GtkMenu* menu = priv->currentMenu;
- priv->currentMenu = NULL;
-
- gtk_menu_popdown(menu);
- g_object_unref(menu);
- }
+ postCommitFrameViewSetup(m_frame, frame->view(), true);
}
}
diff --git a/WebKit/gtk/tests/testwebview.c b/WebKit/gtk/tests/testwebview.c
index 7482747..c028a36 100644
--- a/WebKit/gtk/tests/testwebview.c
+++ b/WebKit/gtk/tests/testwebview.c
@@ -55,6 +55,12 @@ server_callback(SoupServer* server, SoupMessage* msg,
g_assert(!error);
soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, length);
+ } else if (g_str_equal(path, "/bigdiv.html")) {
+ char* contents = g_strdup("<html><body><div style=\"background-color: green; height: 1200px;\"></div></body></html>");
+ soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, strlen(contents));
+ } else if (g_str_equal(path, "/iframe.html")) {
+ char* contents = g_strdup("<html><body><div style=\"background-color: green; height: 50px;\"></div><iframe src=\"bigdiv.html\"></iframe></body></html>");
+ soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, strlen(contents));
} else {
char* contents = g_strdup("<html><body>test</body></html>");
soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, strlen(contents));
@@ -121,6 +127,103 @@ static void test_webkit_web_view_icon_uri()
g_object_unref(view);
}
+static gboolean map_event_cb(GtkWidget *widget, GdkEvent* event, gpointer data)
+{
+ GMainLoop* loop = (GMainLoop*)data;
+ g_main_loop_quit(loop);
+
+ return FALSE;
+}
+
+static void do_test_webkit_web_view_adjustments(gboolean with_page_cache)
+{
+ char* effective_uri = g_strconcat(base_uri, "bigdiv.html", NULL);
+ char* second_uri = g_strconcat(base_uri, "iframe.html", NULL);
+ GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ GtkWidget* scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+ WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ GtkAdjustment* adjustment;
+ double lower;
+ double upper;
+
+ if (with_page_cache) {
+ WebKitWebSettings* settings = webkit_web_view_get_settings(view);
+ g_object_set(settings, "enable-page-cache", TRUE, NULL);
+ }
+
+ gtk_window_set_default_size(GTK_WINDOW(window), 400, 200);
+
+ gtk_container_add(GTK_CONTAINER(window), scrolled_window);
+ gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(view));
+
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ loop = g_main_loop_new(NULL, TRUE);
+
+ g_object_connect(G_OBJECT(view),
+ "signal::notify::progress", idle_quit_loop_cb, NULL,
+ NULL);
+
+ /* Wait for window to show up */
+ gtk_widget_show_all(window);
+ g_signal_connect(window, "map-event",
+ G_CALLBACK(map_event_cb), loop);
+ g_main_loop_run(loop);
+
+ /* Load a page with a big div that will cause scrollbars to appear */
+ webkit_web_view_load_uri(view, effective_uri);
+ g_main_loop_run(loop);
+
+ adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolled_window));
+ g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), ==, 0.0);
+
+ lower = gtk_adjustment_get_lower(adjustment);
+ upper = gtk_adjustment_get_upper(adjustment);
+
+ /* Scroll the view using JavaScript */
+ webkit_web_view_execute_script(view, "window.scrollBy(0, 100)");
+
+ /* Make sure the ScrolledWindow noticed the scroll */
+ g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), ==, 100.0);
+
+ /* Load a second URI */
+ webkit_web_view_load_uri(view, second_uri);
+ g_main_loop_run(loop);
+
+ /* Make sure the scrollbar has been reset */
+ g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), ==, 0.0);
+
+ /* Go back */
+ webkit_web_view_go_back(view);
+
+ /* When using page cache, go_back will return syncronously */
+ if (!with_page_cache)
+ g_main_loop_run(loop);
+
+ /* Make sure GTK+ has time to process the changes in size, for the adjusments */
+ while (gtk_events_pending())
+ gtk_main_iteration();
+
+ /* Make sure upper and lower bounds have been restored correctly */
+ g_assert_cmpfloat(lower, ==, gtk_adjustment_get_lower(adjustment));
+ g_assert_cmpfloat(upper, ==, gtk_adjustment_get_upper(adjustment));
+
+ g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), ==, 100.0);
+
+ g_free(effective_uri);
+ g_free(second_uri);
+
+ gtk_widget_destroy(window);
+}
+
+static void test_webkit_web_view_adjustments()
+{
+ /* Test this with page cache disabled, and enabled. */
+ do_test_webkit_web_view_adjustments(FALSE);
+ do_test_webkit_web_view_adjustments(TRUE);
+}
+
int main(int argc, char** argv)
{
SoupServer* server;
@@ -153,6 +256,7 @@ int main(int argc, char** argv)
g_test_bug_base("https://bugs.webkit.org/");
g_test_add_func("/webkit/webview/icon-uri", test_webkit_web_view_icon_uri);
+ g_test_add_func("/webkit/webview/adjustments", test_webkit_web_view_adjustments);
return g_test_run ();
}
diff --git a/WebKit/gtk/webkit/webkitprivate.h b/WebKit/gtk/webkit/webkitprivate.h
index e9d61a6..44b4d0c 100644
--- a/WebKit/gtk/webkit/webkitprivate.h
+++ b/WebKit/gtk/webkit/webkitprivate.h
@@ -298,6 +298,9 @@ extern "C" {
WEBKIT_API gchar*
webkit_web_frame_counter_value_for_element_by_id (WebKitWebFrame* frame, const gchar* id);
+ WEBKIT_API int
+ webkit_web_frame_page_number_for_element_by_id(WebKitWebFrame* frame, const gchar* id, float pageWidth, float pageHeight);
+
WEBKIT_API guint
webkit_web_frame_get_pending_unload_event_count(WebKitWebFrame* frame);
diff --git a/WebKit/gtk/webkit/webkitwebframe.cpp b/WebKit/gtk/webkit/webkitwebframe.cpp
index 35d9524..fbd246d 100644
--- a/WebKit/gtk/webkit/webkitwebframe.cpp
+++ b/WebKit/gtk/webkit/webkitwebframe.cpp
@@ -269,6 +269,9 @@ static void webkit_web_frame_class_init(WebKitWebFrameClass* frameClass)
* WebKitWebFrame:horizontal-scrollbar-policy and
* WebKitWebFrame:vertical-scrollbar-policy properties.
*
+ * Return value: %TRUE to stop other handlers from being invoked for the
+ * event. %FALSE to propagate the event further.
+ *
* Since: 1.1.14
*/
webkit_web_frame_signals[SCROLLBARS_POLICY_CHANGED] = g_signal_new("scrollbars-policy-changed",
@@ -841,6 +844,29 @@ gchar* webkit_web_frame_counter_value_for_element_by_id(WebKitWebFrame* frame, c
}
/**
+ * webkit_web_frame_page_number_for_element_by_id
+ * @frame: a #WebKitWebFrame
+ * @id: an element ID string
+ * @pageWidth: width of a page
+ * @pageHeight: height of a page
+ *
+ * Return value: The number of page where the specified element will be put
+ */
+int webkit_web_frame_page_number_for_element_by_id(WebKitWebFrame* frame, const gchar* id, float pageWidth, float pageHeight)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
+
+ Frame* coreFrame = core(frame);
+ if (!coreFrame)
+ return -1;
+
+ Element* coreElement = coreFrame->document()->getElementById(AtomicString(id));
+ if (!coreElement)
+ return -1;
+ return PrintContext::pageNumberForElement(coreElement, FloatSize(pageWidth, pageHeight));
+}
+
+/**
* webkit_web_frame_get_pending_unload_event_count:
* @frame: a #WebKitWebFrame
*
diff --git a/WebKit/gtk/webkit/webkitwebview.cpp b/WebKit/gtk/webkit/webkitwebview.cpp
index ad13895..8c5b802 100644
--- a/WebKit/gtk/webkit/webkitwebview.cpp
+++ b/WebKit/gtk/webkit/webkitwebview.cpp
@@ -1325,7 +1325,6 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* WebKitWebView::create-web-view:
* @web_view: the object on which the signal is emitted
* @frame: the #WebKitWebFrame
- * @return: a newly allocated #WebKitWebView or %NULL
*
* Emitted when the creation of a new window is requested.
* If this signal is handled the signal handler should return the
@@ -1338,6 +1337,8 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* the new #WebKitWebView. The widget to which the widget is added will
* handle that.
*
+ * Return value: a newly allocated #WebKitWebView, or %NULL
+ *
* Since: 1.0.3
*/
webkit_web_view_signals[CREATE_WEB_VIEW] = g_signal_new("create-web-view",
@@ -1353,8 +1354,6 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
/**
* WebKitWebView::web-view-ready:
* @web_view: the object on which the signal is emitted
- * @return: %TRUE to stop other handlers from being invoked for
- * the event, %FALSE to propagate the event further
*
* Emitted after #WebKitWebView::create-web-view when the new #WebKitWebView
* should be displayed to the user. When this signal is emitted
@@ -1367,6 +1366,9 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* time of the window, so you may want to connect to the ::notify
* signal of the #WebKitWebWindowFeatures object to handle those.
*
+ * Return value: %TRUE to stop handlers from being invoked for the event or
+ * %FALSE to propagate the event furter
+ *
* Since: 1.0.3
*/
webkit_web_view_signals[WEB_VIEW_READY] = g_signal_new("web-view-ready",
@@ -1381,14 +1383,15 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
/**
* WebKitWebView::close-web-view:
* @web_view: the object on which the signal is emitted
- * @return: %TRUE to stop handlers from being invoked for the event or
- * %FALSE to propagate the event furter
*
* Emitted when closing a #WebKitWebView is requested. This occurs when a
* call is made from JavaScript's window.close function. The default
* signal handler does not do anything. It is the owner's responsibility
* to hide or delete the web view, if necessary.
*
+ * Return value: %TRUE to stop handlers from being invoked for the event or
+ * %FALSE to propagate the event furter
+ *
* Since: 1.1.11
*/
webkit_web_view_signals[CLOSE_WEB_VIEW] = g_signal_new("close-web-view",
@@ -1405,10 +1408,11 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* @web_view: the object on which the signal is emitted
* @frame: the #WebKitWebFrame that required the navigation
* @request: a #WebKitNetworkRequest
- * @return: a WebKitNavigationResponse
*
* Emitted when @frame requests a navigation to another page.
*
+ * Return value: a #WebKitNavigationResponse
+ *
* Deprecated: Use WebKitWebView::navigation-policy-decision-requested
* instead
*/
@@ -1430,8 +1434,6 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* @request: a #WebKitNetworkRequest
* @navigation_action: a #WebKitWebNavigation
* @policy_decision: a #WebKitWebPolicyDecision
- * @return: TRUE if a decision was made, FALSE to have the
- * default behavior apply
*
* Emitted when @frame requests opening a new window. With this
* signal the browser can use the context of the request to decide
@@ -1453,6 +1455,9 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* webkit_web_policy_decision_download() on the @policy_decision
* object.
*
+ * Return value: %TRUE if a decision was made, %FALSE to have the
+ * default behavior apply
+ *
* Since: 1.1.4
*/
webkit_web_view_signals[NEW_WINDOW_POLICY_DECISION_REQUESTED] =
@@ -1476,8 +1481,6 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* @request: a #WebKitNetworkRequest
* @navigation_action: a #WebKitWebNavigation
* @policy_decision: a #WebKitWebPolicyDecision
- * @return: TRUE if a decision was made, FALSE to have the
- * default behavior apply
*
* Emitted when @frame requests a navigation to another page.
* If this signal is not handled, the default behavior is to allow the
@@ -1490,6 +1493,9 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* webkit_web_policy_decision_download() on the @policy_decision
* object.
*
+ * Return value: %TRUE if a decision was made, %FALSE to have the
+ * default behavior apply
+ *
* Since: 1.0.3
*/
webkit_web_view_signals[NAVIGATION_POLICY_DECISION_REQUESTED] = g_signal_new("navigation-policy-decision-requested",
@@ -1512,8 +1518,6 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* @request: a WebKitNetworkRequest
* @mimetype: the MIME type attempted to load
* @policy_decision: a #WebKitWebPolicyDecision
- * @return: TRUE if a decision was made, FALSE to have the
- * default behavior apply
*
* Decide whether or not to display the given MIME type. If this
* signal is not handled, the default behavior is to show the
@@ -1531,6 +1535,9 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* webkit_web_policy_decision_download() on the @policy_decision
* object.
*
+ * Return value: %TRUE if a decision was made, %FALSE to have the
+ * default behavior apply
+ *
* Since: 1.0.3
*/
webkit_web_view_signals[MIME_TYPE_POLICY_DECISION_REQUESTED] = g_signal_new("mime-type-policy-decision-requested",
@@ -1578,7 +1585,6 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* @web_view: the object on which the signal is emitted
* @download: a #WebKitDownload object that lets you control the
* download process
- * @return: %TRUE if the download should be performed, %FALSE to cancel it.
*
* A new Download is being requested. By default, if the signal is
* not handled, the download is cancelled. If you handle the download
@@ -1601,6 +1607,9 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* is to download anything that WebKit can't handle, which you can
* figure out by using webkit_web_view_can_show_mime_type()).
*
+ * Return value: TRUE if the download should be performed, %FALSE to
+ * cancel it
+ *
* Since: 1.1.2
*/
webkit_web_view_signals[DOWNLOAD_REQUESTED] = g_signal_new("download-requested",
@@ -1681,6 +1690,9 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* handle the signal if you want to provide your own error page.
*
* Since: 1.1.6
+ *
+ * Return value: %TRUE to stop other handlers from being invoked for the
+ * event. %FALSE to propagate the event further.
*/
webkit_web_view_signals[LOAD_ERROR] = g_signal_new("load-error",
G_TYPE_FROM_CLASS(webViewClass),
@@ -1774,8 +1786,6 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* WebKitWebView::print-requested
* @web_view: the object in which the signal is emitted
* @web_frame: the frame that is requesting to be printed
- * @return: %TRUE if the print request has been handled, %FALSE if
- * the default handler should run
*
* Emitted when printing is requested by the frame, usually
* because of a javascript call. When handling this signal you
@@ -1787,6 +1797,9 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* ignore a print request you must connect to this signal, and
* return %TRUE.
*
+ * Return value: %TRUE if the print request has been handled, %FALSE if
+ * the default handler should run
+ *
* Since: 1.1.5
*/
webkit_web_view_signals[PRINT_REQUESTED] = g_signal_new("print-requested",
@@ -1843,9 +1856,11 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* @message: the message text
* @line: the line where the error occured
* @source_id: the source id
- * @return: TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further.
*
* A JavaScript console message was created.
+ *
+ * Return value: %TRUE to stop other handlers from being invoked for the
+ * event. %FALSE to propagate the event further.
*/
webkit_web_view_signals[CONSOLE_MESSAGE] = g_signal_new("console-message",
G_TYPE_FROM_CLASS(webViewClass),
@@ -1862,9 +1877,11 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* @web_view: the object on which the signal is emitted
* @frame: the relevant frame
* @message: the message text
- * @return: TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further.
*
* A JavaScript alert dialog was created.
+ *
+ * Return value: %TRUE to stop other handlers from being invoked for the
+ * event. %FALSE to propagate the event further.
*/
webkit_web_view_signals[SCRIPT_ALERT] = g_signal_new("script-alert",
G_TYPE_FROM_CLASS(webViewClass),
@@ -1882,9 +1899,11 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* @frame: the relevant frame
* @message: the message text
* @confirmed: whether the dialog has been confirmed
- * @return: TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further.
*
* A JavaScript confirm dialog was created, providing Yes and No buttons.
+ *
+ * Return value: %TRUE to stop other handlers from being invoked for the
+ * event. %FALSE to propagate the event further.
*/
webkit_web_view_signals[SCRIPT_CONFIRM] = g_signal_new("script-confirm",
G_TYPE_FROM_CLASS(webViewClass),
@@ -1903,9 +1922,11 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* @message: the message text
* @default: the default value
* @text: To be filled with the return value or NULL if the dialog was cancelled.
- * @return: TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further.
*
* A JavaScript prompt dialog was created, providing an entry to input text.
+ *
+ * Return value: %TRUE to stop other handlers from being invoked for the
+ * event. %FALSE to propagate the event further.
*/
webkit_web_view_signals[SCRIPT_PROMPT] = g_signal_new("script-prompt",
G_TYPE_FROM_CLASS(webViewClass),
@@ -2032,6 +2053,8 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
*
* The #WebKitWebView::move-cursor will be emitted to apply the
* cursor movement described by its parameters to the @view.
+ *
+ * Return value: %TRUE or %FALSE
*
* Since: 1.1.4
*/
@@ -2059,6 +2082,8 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
* to set the property value of "webkit-widget-is-selected". This can
* be used to draw a visual indicator of the selection.
*
+ * Return value: a new #GtkWidget, or %NULL
+ *
* Since: 1.1.8
*/
webkit_web_view_signals[PLUGIN_WIDGET] = g_signal_new("create-plugin-widget",
diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog
index 8bbd4de..b545a40 100644
--- a/WebKit/mac/ChangeLog
+++ b/WebKit/mac/ChangeLog
@@ -1,3 +1,189 @@
+2010-02-12 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/7615234> REGRESSION (r48586): Loading an HTML page causes
+ PDFKit to be loaded
+
+ * WebView/WebPDFDocumentExtras.h: Removed the category declaration and
+ addWebPDFDocumentExtras(). Declare allScriptsInPDFDocument().
+ * WebView/WebPDFDocumentExtras.mm:
+ (allScriptsInPDFDocument): Changed the -_web_allScripts method into this function.
+ * WebView/WebPDFRepresentation.mm: Removed +initialize.
+ (-[WebPDFRepresentation finishedLoadingWithDataSource:]): Use
+ allScriptsInPDFDocument() instead of -_web_allScripts.
+
+2010-02-10 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Exported some new JavaScript heap introspection.
+
+ * Misc/WebCoreStatistics.h:
+ * Misc/WebCoreStatistics.mm:
+ (+[WebCoreStatistics javaScriptObjectTypeCounts]): Just like
+ javaScriptProtectedObjectTypeCounts, except this function enumerates all
+ live objects, not just protected objects.
+
+2010-02-08 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Restore ENABLE_RUBY flag so vendors can ship with Ruby disabled if they choose.
+ https://bugs.webkit.org/show_bug.cgi?id=34698
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2010-02-09 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34490
+ WebCore::ImageEventSender::dispatchPendingEvents() crashes in certain conditions
+
+ * ForwardingHeaders/wtf/ValueCheck.h: Added.
+
+2010-02-10 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Support frameset flattening
+ https://bugs.webkit.org/show_bug.cgi?id=32717
+
+ Add support for enabling/disabling FrameSet Flattening on the Mac port.
+
+ * WebView/WebPreferenceKeysPrivate.h:
+ * WebView/WebPreferences.mm:
+ (+[WebPreferences initialize]):
+ (-[WebPreferences isFrameSetFlatteningEnabled]):
+ (-[WebPreferences setFrameSetFlatteningEnabled:]):
+ * WebView/WebPreferencesPrivate.h:
+ * WebView/WebView.mm:
+ (-[WebView _preferencesChangedNotification:]):
+
+2010-02-09 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Anders Carlsson.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34771
+ A stray mouse moved event is sent to plug-ins after mouse exit
+
+ * WebCoreSupport/WebFrameLoaderClient.mm: (NetscapePluginWidget::handleEvent): A mouseout
+ DOM event is dispatched while handling NSMouseMoved - but we shouldn't be sending a
+ mouse moved event to plug-ins at this point.
+
+2010-02-09 Shinichiro Hamaji <hamaji@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Provide a way to get total number of pages to be printed
+ https://bugs.webkit.org/show_bug.cgi?id=34699
+
+ * Misc/WebCoreStatistics.h:
+ * Misc/WebCoreStatistics.mm:
+ (-[WebFrame numberOfPages:pageWidthInPixels:]):
+
+2010-02-08 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34727
+ Assertion crashes and freezes when plug-in property access results in an exception
+
+ * Plugins/Hosted/WebKitPluginClient.defs: Made PCSetProperty and PCRemoveProperty async.
+ A plug-in can call back whil processing this call (e.g. for NPN_SetException), so we need
+ to listen for messages while waiting for reply.
+
+ * Plugins/Hosted/NetscapePluginHostProxy.mm:
+ (WKPCEvaluate): If there is no instance proxy, return KERN_FAILURE. This improves consistency
+ between method implementations, and leaves us with one less IPC call to make in failure case
+ (returning false with KERN_SUCCESS and returning KERN_FAILURE looks the same from plugin
+ host code).
+ (WKPCInvoke): Ditto.
+ (WKPCInvokeDefault): Ditto.
+ (WKPCGetProperty): Ditto.
+ (WKPCSetProperty): Send a reply once done.
+ (WKPCRemoveProperty): Ditto.
+ (WKPCHasProperty): If there is no instance proxy, return KERN_FAILURE.
+ (WKPCHasMethod): Ditto.
+ (WKPCEnumerate): Ditto.
+
+2010-02-08 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Anders Carlsson.
+
+ <rdar://problem/6530010> OOP: Support NPN_SetException
+
+ Tested by plugins/netscape-throw-exception.html (removed it from skipped list).
+
+ * Plugins/Hosted/NetscapePluginHostProxy.mm:
+ (WKPCSetException):
+ * Plugins/Hosted/NetscapePluginInstanceProxy.h:
+ * Plugins/Hosted/NetscapePluginInstanceProxy.mm:
+ (WebKit::globalExceptionString):
+ (WebKit::NetscapePluginInstanceProxy::setGlobalException):
+ (WebKit::NetscapePluginInstanceProxy::moveGlobalExceptionToExecState):
+ * Plugins/Hosted/ProxyInstance.mm:
+ (WebKit::ProxyInstance::invoke):
+ (WebKit::ProxyInstance::getPropertyNames):
+ (WebKit::ProxyInstance::fieldValue):
+ (WebKit::ProxyInstance::setFieldValue):
+ * Plugins/Hosted/WebKitPluginClient.defs:
+ Route exception string to a global that's checked after calling into plug-in (just like in
+ in-process case).
+
+2010-02-05 Kevin Decker <kdecker@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34661
+ <rdar://problem/7614067> REGRESSION (Safari 4.0-> Safari 4.0.4): NPP_SetWindow no longer sets a clipRect of (0,0,0,0) when it becomes hidden
+
+ * Plugins/Hosted/WebHostedNetscapePluginView.mm:
+ (-[WebHostedNetscapePluginView updateAndSetWindow]): When clipping out NPDrawingModelCoreAnimation plug-ins, provide a zero'd out clipRect.
+ * Plugins/WebBaseNetscapePluginView.h: Moved superviewsHaveSuperviews to the base class.
+ * Plugins/WebBaseNetscapePluginView.mm:
+ (-[WebBaseNetscapePluginView superviewsHaveSuperviews]): Added to the base class; extracted from WebNetscapePluginView.
+ (-[WebBaseNetscapePluginView shouldClipOutPlugin]): Added new method with code extracted from WebNetscapePluginView.
+ * Plugins/WebNetscapePluginView.mm:
+ (-[WebNetscapePluginView saveAndSetNewPortStateForUpdate:]): When clipping out NPDrawingModelCoreAnimation plug-ins, provide a zero'd out clipRect.
+
+2010-02-04 Mark Rowe <mrowe@apple.com>
+
+ Rubber-stamped by Dan Bernstein.
+
+ Fix the ability to #include <WebKit/DOMFile.h>.
+
+ * MigrateHeaders.make: Mark DOMBlob.h as a public header since the already-public DOMFile.h depends on it.
+
+2010-02-04 John Sullivan <sullivan@apple.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=34611
+ WebLocalizedString() could use an assertion that it is being called on the main thread
+
+ Reviewed by Tim Hatcher.
+
+ * Misc/WebLocalizableStrings.m: Removed.
+ * Misc/WebLocalizableStrings.mm: Copied from mac/Misc/WebLocalizableStrings.m.
+ Renamed to use .mm extension so it can include a C++ header.
+ (WebLocalizedString):
+ Added an assertion that this is being called on the main thread.
+
+2010-02-04 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ REGRESSION (r53718): When scrolling a tall window by page, the overlap between pages is too big
+ https://bugs.webkit.org/show_bug.cgi?id=34371
+
+ * WebView/WebFrameView.mm:
+ (-[WebFrameView _verticalPageScrollDistance]): Use Scrollbar methods instead of
+ constants, and cap the scroll distance.
+ (-[WebFrameView initWithFrame:]): Use Scrollbar::pixelsPerLineStep() instead of
+ cScrollbarPixelsPerLineStep.
+ (-[WebFrameView _horizontalPageScrollDistance]):Use Scrollbar methods instead of
+ constants, and cap the scroll distance.
+
2010-02-01 Shinichiro Hamaji <hamaji@chromium.org>
Reviewed by Eric Seidel.
diff --git a/WebKit/mac/Configurations/FeatureDefines.xcconfig b/WebKit/mac/Configurations/FeatureDefines.xcconfig
index 24589c7..8343ce7 100644
--- a/WebKit/mac/Configurations/FeatureDefines.xcconfig
+++ b/WebKit/mac/Configurations/FeatureDefines.xcconfig
@@ -56,6 +56,7 @@ ENABLE_JAVASCRIPT_DEBUGGER = ENABLE_JAVASCRIPT_DEBUGGER;
ENABLE_MATHML = ;
ENABLE_NOTIFICATIONS = ;
ENABLE_OFFLINE_WEB_APPLICATIONS = ENABLE_OFFLINE_WEB_APPLICATIONS;
+ENABLE_RUBY = ENABLE_RUBY;
ENABLE_SHARED_WORKERS = ENABLE_SHARED_WORKERS;
ENABLE_SVG = ENABLE_SVG;
ENABLE_SVG_ANIMATION = ENABLE_SVG_ANIMATION;
@@ -72,4 +73,4 @@ ENABLE_XHTMLMP = ;
ENABLE_XPATH = ENABLE_XPATH;
ENABLE_XSLT = ENABLE_XSLT;
-FEATURE_DEFINES = $(ENABLE_3D_CANVAS) $(ENABLE_3D_RENDERING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_DATABASE) $(ENABLE_DATAGRID) $(ENABLE_DATALIST) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_VIDEO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WML) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_CANVAS) $(ENABLE_3D_RENDERING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_DATABASE) $(ENABLE_DATAGRID) $(ENABLE_DATALIST) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_RUBY) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_VIDEO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WML) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT);
diff --git a/WebKit/mac/Configurations/Version.xcconfig b/WebKit/mac/Configurations/Version.xcconfig
index 75f9bd4..0e289b1 100644
--- a/WebKit/mac/Configurations/Version.xcconfig
+++ b/WebKit/mac/Configurations/Version.xcconfig
@@ -21,8 +21,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-MAJOR_VERSION = 532;
-MINOR_VERSION = 9;
+MAJOR_VERSION = 533;
+MINOR_VERSION = 1;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/WebKit/mac/ForwardingHeaders/wtf/ValueCheck.h b/WebKit/mac/ForwardingHeaders/wtf/ValueCheck.h
new file mode 100644
index 0000000..7a067ff
--- /dev/null
+++ b/WebKit/mac/ForwardingHeaders/wtf/ValueCheck.h
@@ -0,0 +1 @@
+#import <JavaScriptCore/ValueCheck.h>
diff --git a/WebKit/mac/MigrateHeaders.make b/WebKit/mac/MigrateHeaders.make
index 7d01c99..f4bf744 100644
--- a/WebKit/mac/MigrateHeaders.make
+++ b/WebKit/mac/MigrateHeaders.make
@@ -36,7 +36,7 @@ all : \
$(PUBLIC_HEADERS_DIR)/DOM.h \
$(PUBLIC_HEADERS_DIR)/DOMAbstractView.h \
$(PUBLIC_HEADERS_DIR)/DOMAttr.h \
- $(PRIVATE_HEADERS_DIR)/DOMBlob.h \
+ $(PUBLIC_HEADERS_DIR)/DOMBlob.h \
$(INTERNAL_HEADERS_DIR)/DOMBlobInternal.h \
$(PUBLIC_HEADERS_DIR)/DOMCDATASection.h \
$(PUBLIC_HEADERS_DIR)/DOMCSS.h \
diff --git a/WebKit/mac/Misc/WebCoreStatistics.h b/WebKit/mac/Misc/WebCoreStatistics.h
index 6c45fb9..d205083 100644
--- a/WebKit/mac/Misc/WebCoreStatistics.h
+++ b/WebKit/mac/Misc/WebCoreStatistics.h
@@ -43,6 +43,7 @@
+ (size_t)javaScriptProtectedObjectsCount;
+ (size_t)javaScriptProtectedGlobalObjectsCount;
+ (NSCountedSet *)javaScriptProtectedObjectTypeCounts;
++ (NSCountedSet *)javaScriptObjectTypeCounts;
+ (void)garbageCollectJavaScriptObjects;
+ (void)garbageCollectJavaScriptObjectsOnAlternateThreadForDebugging:(BOOL)waitUntilDone;
@@ -85,4 +86,5 @@
- (NSString *)renderTreeAsExternalRepresentation;
- (NSString *)counterValueForElement:(DOMElement*)element;
- (int)pageNumberForElement:(DOMElement*)element:(float)pageWidthInPixels:(float)pageHeightInPixels;
+- (int)numberOfPages:(float)pageWidthInPixels:(float)pageHeightInPixels;
@end
diff --git a/WebKit/mac/Misc/WebCoreStatistics.mm b/WebKit/mac/Misc/WebCoreStatistics.mm
index b18ee29..9e8ae05 100644
--- a/WebKit/mac/Misc/WebCoreStatistics.mm
+++ b/WebKit/mac/Misc/WebCoreStatistics.mm
@@ -93,6 +93,21 @@ using namespace WebCore;
return result;
}
++ (NSCountedSet *)javaScriptObjectTypeCounts
+{
+ JSLock lock(SilenceAssertionsOnly);
+
+ NSCountedSet *result = [NSCountedSet set];
+
+ OwnPtr<HashCountedSet<const char*> > counts(JSDOMWindow::commonJSGlobalData()->heap.objectTypeCounts());
+ HashCountedSet<const char*>::iterator end = counts->end();
+ for (HashCountedSet<const char*>::iterator it = counts->begin(); it != end; ++it)
+ for (unsigned i = 0; i < it->second; ++i)
+ [result addObject:[NSString stringWithUTF8String:it->first]];
+
+ return result;
+}
+
+ (void)garbageCollectJavaScriptObjects
{
gcController().garbageCollectNow();
@@ -256,4 +271,9 @@ using namespace WebCore;
return PrintContext::pageNumberForElement(core(element), FloatSize(pageWidthInPixels, pageHeightInPixels));
}
+- (int)numberOfPages:(float)pageWidthInPixels:(float)pageHeightInPixels
+{
+ return PrintContext::numberOfPages(_private->coreFrame, FloatSize(pageWidthInPixels, pageHeightInPixels));
+}
+
@end
diff --git a/WebKit/mac/Misc/WebLocalizableStrings.m b/WebKit/mac/Misc/WebLocalizableStrings.mm
index 0babfbc..4006bb7 100644
--- a/WebKit/mac/Misc/WebLocalizableStrings.m
+++ b/WebKit/mac/Misc/WebLocalizableStrings.mm
@@ -29,11 +29,18 @@
#import <WebKit/WebLocalizableStrings.h>
#import <wtf/Assertions.h>
+#import <wtf/Threading.h>
WebLocalizableStringsBundle WebKitLocalizableStringsBundle = { "com.apple.WebKit", 0 };
NSString *WebLocalizedString(WebLocalizableStringsBundle *stringsBundle, const char *key)
{
+ // This function is not thread-safe due at least to its unguarded use of the mainBundle static variable
+ // and its use of [NSBundle localizedStringForKey:::], which is not guaranteed to be thread-safe. If
+ // we decide we need to use this on background threads, we'll need to add locking here and make sure
+ // it doesn't affect performance.
+ ASSERT(isMainThread());
+
NSBundle *bundle;
if (stringsBundle == NULL) {
static NSBundle *mainBundle;
diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm b/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm
index 0e6c9a3..c5beb07 100644
--- a/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm
+++ b/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm
@@ -39,6 +39,7 @@
#import <WebCore/Frame.h>
#import <WebCore/IdentifierRep.h>
#import <WebCore/ScriptController.h>
+#import <string>
extern "C" {
#import "WebKitPluginHost.h"
@@ -568,10 +569,8 @@ kern_return_t WKPCEvaluate(mach_port_t clientPort, uint32_t pluginID, uint32_t r
return KERN_FAILURE;
NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
- if (!instanceProxy) {
- _WKPHBooleanAndDataReply(hostProxy->port(), pluginID, requestID, false, 0, 0);
- return KERN_SUCCESS;
- }
+ if (!instanceProxy)
+ return KERN_FAILURE;
PluginDestroyDeferrer deferrer(instanceProxy);
@@ -625,18 +624,14 @@ kern_return_t WKPCInvoke(mach_port_t clientPort, uint32_t pluginID, uint32_t req
return KERN_FAILURE;
NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
- if (!instanceProxy) {
- _WKPHBooleanAndDataReply(hostProxy->port(), pluginID, requestID, false, 0, 0);
- return KERN_SUCCESS;
- }
+ if (!instanceProxy)
+ return KERN_FAILURE;
PluginDestroyDeferrer deferrer(instanceProxy);
IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
- if (!IdentifierRep::isValid(identifier)) {
- _WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, false, 0, 0);
- return KERN_SUCCESS;
- }
+ if (!IdentifierRep::isValid(identifier))
+ return KERN_FAILURE;
Identifier methodNameIdentifier = identifierFromIdentifierRep(identifier);
@@ -661,10 +656,8 @@ kern_return_t WKPCInvokeDefault(mach_port_t clientPort, uint32_t pluginID, uint3
return KERN_FAILURE;
NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
- if (!instanceProxy) {
- _WKPHBooleanAndDataReply(hostProxy->port(), pluginID, requestID, false, 0, 0);
- return KERN_SUCCESS;
- }
+ if (!instanceProxy)
+ return KERN_FAILURE;
PluginDestroyDeferrer deferrer(instanceProxy);
@@ -707,16 +700,12 @@ kern_return_t WKPCGetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_
return KERN_FAILURE;
NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
- if (!instanceProxy) {
- _WKPHBooleanAndDataReply(hostProxy->port(), pluginID, requestID, false, 0, 0);
- return KERN_SUCCESS;
- }
+ if (!instanceProxy)
+ return KERN_FAILURE;
IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
- if (!IdentifierRep::isValid(identifier)) {
- _WKPHBooleanAndDataReply(hostProxy->port(), pluginID, requestID, false, 0, 0);
- return KERN_SUCCESS;
- }
+ if (!IdentifierRep::isValid(identifier))
+ return KERN_FAILURE;
PluginDestroyDeferrer deferrer(instanceProxy);
@@ -737,7 +726,7 @@ kern_return_t WKPCGetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_
return KERN_SUCCESS;
}
-kern_return_t WKPCSetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID, uint64_t serverIdentifier, data_t valueData, mach_msg_type_number_t valueLength, boolean_t* returnValue)
+kern_return_t WKPCSetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, uint64_t serverIdentifier, data_t valueData, mach_msg_type_number_t valueLength)
{
DataDeallocator deallocator(valueData, valueLength);
@@ -753,18 +742,21 @@ kern_return_t WKPCSetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_
IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
if (!IdentifierRep::isValid(identifier))
- *returnValue = false;
-
+ return KERN_FAILURE;
+
+ bool result;
if (identifier->isString()) {
Identifier propertyNameIdentifier = identifierFromIdentifierRep(identifier);
- *returnValue = instanceProxy->setProperty(objectID, propertyNameIdentifier, valueData, valueLength);
+ result = instanceProxy->setProperty(objectID, propertyNameIdentifier, valueData, valueLength);
} else
- *returnValue = instanceProxy->setProperty(objectID, identifier->number(), valueData, valueLength);
-
+ result = instanceProxy->setProperty(objectID, identifier->number(), valueData, valueLength);
+
+ _WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, result);
+
return KERN_SUCCESS;
}
-kern_return_t WKPCRemoveProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID, uint64_t serverIdentifier, boolean_t* returnValue)
+kern_return_t WKPCRemoveProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, uint64_t serverIdentifier)
{
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
@@ -779,13 +771,16 @@ kern_return_t WKPCRemoveProperty(mach_port_t clientPort, uint32_t pluginID, uint
IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
if (!IdentifierRep::isValid(identifier))
return KERN_FAILURE;
-
+
+ bool result;
if (identifier->isString()) {
Identifier propertyNameIdentifier = identifierFromIdentifierRep(identifier);
- *returnValue = instanceProxy->removeProperty(objectID, propertyNameIdentifier);
+ result = instanceProxy->removeProperty(objectID, propertyNameIdentifier);
} else
- *returnValue = instanceProxy->removeProperty(objectID, identifier->number());
-
+ result = instanceProxy->removeProperty(objectID, identifier->number());
+
+ _WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, result);
+
return KERN_SUCCESS;
}
@@ -796,18 +791,14 @@ kern_return_t WKPCHasProperty(mach_port_t clientPort, uint32_t pluginID, uint32_
return KERN_FAILURE;
NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
- if (!instanceProxy) {
- _WKPHBooleanReply(hostProxy->port(), pluginID, requestID, false);
- return KERN_SUCCESS;
- }
+ if (!instanceProxy)
+ return KERN_FAILURE;
PluginDestroyDeferrer deferrer(instanceProxy);
IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
- if (!IdentifierRep::isValid(identifier)) {
- _WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, false);
- return KERN_SUCCESS;
- }
+ if (!IdentifierRep::isValid(identifier))
+ return KERN_FAILURE;
boolean_t returnValue;
if (identifier->isString()) {
@@ -828,18 +819,14 @@ kern_return_t WKPCHasMethod(mach_port_t clientPort, uint32_t pluginID, uint32_t
return KERN_FAILURE;
NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
- if (!instanceProxy) {
- _WKPHBooleanReply(hostProxy->port(), pluginID, requestID, false);
- return KERN_SUCCESS;
- }
+ if (!instanceProxy)
+ return KERN_FAILURE;
PluginDestroyDeferrer deferrer(instanceProxy);
IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
- if (!IdentifierRep::isValid(identifier)) {
- _WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, false);
- return KERN_SUCCESS;
- }
+ if (!IdentifierRep::isValid(identifier))
+ return KERN_FAILURE;
Identifier methodNameIdentifier = identifierFromIdentifierRep(identifier);
boolean_t returnValue = instanceProxy->hasMethod(objectID, methodNameIdentifier);
@@ -880,10 +867,8 @@ kern_return_t WKPCEnumerate(mach_port_t clientPort, uint32_t pluginID, uint32_t
return KERN_FAILURE;
NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
- if (!instanceProxy) {
- _WKPHBooleanAndDataReply(hostProxy->port(), pluginID, requestID, false, 0, 0);
- return KERN_SUCCESS;
- }
+ if (!instanceProxy)
+ return KERN_FAILURE;
data_t resultData = 0;
mach_msg_type_number_t resultLength = 0;
@@ -1149,4 +1134,14 @@ kern_return_t WKPCRunSyncOpenPanel(mach_port_t clientPort, data_t panelData, mac
}
#endif // !defined(BUILDING_ON_SNOW_LEOPARD)
+kern_return_t WKPCSetException(mach_port_t clientPort, data_t message, mach_msg_type_number_t messageCnt)
+{
+ DataDeallocator deallocator(message, messageCnt);
+
+ string str(message, messageCnt);
+ NetscapePluginInstanceProxy::setGlobalException(str.c_str());
+
+ return KERN_SUCCESS;
+}
+
#endif // USE(PLUGIN_HOST_PROCESS)
diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h
index 2ef6b02..76981a4 100644
--- a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h
+++ b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h
@@ -140,7 +140,7 @@ public:
data_t& usernameData, mach_msg_type_number_t& usernameLength, data_t& passwordData, mach_msg_type_number_t& passwordLength);
bool convertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
double& destX, double& destY, NPCoordinateSpace destSpace);
-
+
PassRefPtr<JSC::Bindings::Instance> createBindingsInstance(PassRefPtr<JSC::Bindings::RootObject>);
RetainPtr<NSData *> marshalValues(JSC::ExecState*, const JSC::ArgList& args);
void marshalValue(JSC::ExecState*, JSC::JSValue value, data_t& resultData, mach_msg_type_number_t& resultLength);
@@ -167,6 +167,9 @@ public:
void didDraw();
void privateBrowsingModeDidChange(bool isPrivateBrowsingEnabled);
+ static void setGlobalException(const WebCore::String&);
+ static void moveGlobalExceptionToExecState(JSC::ExecState*);
+
// Reply structs
struct Reply {
enum Type {
diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
index e4fe1d2..c09e3ea 100644
--- a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
+++ b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
@@ -40,6 +40,7 @@
#import "WebUIDelegate.h"
#import "WebUIDelegatePrivate.h"
#import "WebViewInternal.h"
+#import <JavaScriptCore/Error.h>
#import <JavaScriptCore/JSLock.h>
#import <JavaScriptCore/PropertyNameArray.h>
#import <WebCore/CString.h>
@@ -1492,6 +1493,30 @@ void NetscapePluginInstanceProxy::privateBrowsingModeDidChange(bool isPrivateBro
_WKPHPluginInstancePrivateBrowsingModeDidChange(m_pluginHostProxy->port(), m_pluginID, isPrivateBrowsingEnabled);
}
+static String& globalExceptionString()
+{
+ DEFINE_STATIC_LOCAL(String, exceptionString, ());
+ return exceptionString;
+}
+
+void NetscapePluginInstanceProxy::setGlobalException(const String& exception)
+{
+ globalExceptionString() = exception;
+}
+
+void NetscapePluginInstanceProxy::moveGlobalExceptionToExecState(ExecState* exec)
+{
+ if (globalExceptionString().isNull())
+ return;
+
+ {
+ JSLock lock(SilenceAssertionsOnly);
+ throwError(exec, GeneralError, globalExceptionString());
+ }
+
+ globalExceptionString() = UString();
+}
+
} // namespace WebKit
#endif // USE(PLUGIN_HOST_PROCESS)
diff --git a/WebKit/mac/Plugins/Hosted/ProxyInstance.mm b/WebKit/mac/Plugins/Hosted/ProxyInstance.mm
index 1af2ef8..1587ad0 100644
--- a/WebKit/mac/Plugins/Hosted/ProxyInstance.mm
+++ b/WebKit/mac/Plugins/Hosted/ProxyInstance.mm
@@ -147,6 +147,7 @@ JSValue ProxyInstance::invoke(JSC::ExecState* exec, InvokeType type, uint64_t id
return jsUndefined();
auto_ptr<NetscapePluginInstanceProxy::BooleanAndDataReply> reply = waitForReply<NetscapePluginInstanceProxy::BooleanAndDataReply>(requestID);
+ NetscapePluginInstanceProxy::moveGlobalExceptionToExecState(exec);
if (!reply.get() || !reply->m_returnValue)
return jsUndefined();
@@ -253,7 +254,7 @@ void ProxyInstance::getPropertyNames(ExecState* exec, PropertyNameArray& nameArr
return;
auto_ptr<NetscapePluginInstanceProxy::BooleanAndDataReply> reply = waitForReply<NetscapePluginInstanceProxy::BooleanAndDataReply>(requestID);
-
+ NetscapePluginInstanceProxy::moveGlobalExceptionToExecState(exec);
if (!reply.get() || !reply->m_returnValue)
return;
@@ -361,6 +362,7 @@ JSC::JSValue ProxyInstance::fieldValue(ExecState* exec, const Field* field) cons
return jsUndefined();
auto_ptr<NetscapePluginInstanceProxy::BooleanAndDataReply> reply = waitForReply<NetscapePluginInstanceProxy::BooleanAndDataReply>(requestID);
+ NetscapePluginInstanceProxy::moveGlobalExceptionToExecState(exec);
if (!reply.get() || !reply->m_returnValue)
return jsUndefined();
@@ -387,6 +389,7 @@ void ProxyInstance::setFieldValue(ExecState* exec, const Field* field, JSValue v
return;
auto_ptr<NetscapePluginInstanceProxy::BooleanReply> reply = waitForReply<NetscapePluginInstanceProxy::BooleanReply>(requestID);
+ NetscapePluginInstanceProxy::moveGlobalExceptionToExecState(exec);
}
void ProxyInstance::invalidate()
diff --git a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
index 9baa328..42f0877 100644
--- a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
+++ b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
@@ -161,12 +161,24 @@ extern "C" {
// Use AppKit to convert view coordinates to NSWindow coordinates.
NSRect boundsInWindow = [self convertRect:[self bounds] toView:nil];
- NSRect visibleRectInWindow = [self convertRect:[self visibleRect] toView:nil];
+ NSRect visibleRectInWindow;
+
+ // Core Animation plug-ins need to be updated (with a 0,0,0,0 clipRect) when
+ // moved to a background tab. We don't do this for Core Graphics plug-ins as
+ // older versions of Flash have historical WebKit-specific code that isn't
+ // compatible with this behavior.
+ BOOL shouldClipOutPlugin = _pluginLayer && [self shouldClipOutPlugin];
+ if (!shouldClipOutPlugin)
+ visibleRectInWindow = [self convertRect:[self visibleRect] toView:nil];
+ else
+ visibleRectInWindow = NSZeroRect;
// Flip Y to convert NSWindow coordinates to top-left-based window coordinates.
float borderViewHeight = [[self currentWindow] frame].size.height;
boundsInWindow.origin.y = borderViewHeight - NSMaxY(boundsInWindow);
- visibleRectInWindow.origin.y = borderViewHeight - NSMaxY(visibleRectInWindow);
+
+ if (!shouldClipOutPlugin)
+ visibleRectInWindow.origin.y = borderViewHeight - NSMaxY(visibleRectInWindow);
BOOL sizeChanged = !NSEqualSizes(_previousSize, boundsInWindow.size);
_previousSize = boundsInWindow.size;
diff --git a/WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs b/WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs
index 0cf4005..58a7996 100644
--- a/WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs
+++ b/WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs
@@ -149,18 +149,18 @@ simpleroutine PCGetProperty(clientPort :mach_port_t;
objectID :uint32_t;
propertyNameIdentifier :uint64_t);
-routine PCSetProperty(clientPort :mach_port_t;
+simpleroutine PCSetProperty(clientPort :mach_port_t;
pluginID :uint32_t;
+ requestID :uint32_t;
objectID :uint32_t;
propertyNameIdentifier :uint64_t;
- value :data_t;
- out returnValue :boolean_t);
+ value :data_t);
-routine PCRemoveProperty(clientPort :mach_port_t;
+simpleroutine PCRemoveProperty(clientPort :mach_port_t;
pluginID :uint32_t;
+ requestID :uint32_t;
objectID :uint32_t;
- propertyNameIdentifier :uint64_t;
- out returnValue :boolean_t);
+ propertyNameIdentifier :uint64_t);
simpleroutine PCHasProperty(clientPort :mach_port_t;
pluginID :uint32_t;
@@ -236,3 +236,6 @@ simpleroutine PCRunSyncOpenPanel(clientPort :mach_port_t;
simpleroutine PCSetFullScreenWindowIsShowing(clientPort :mach_port_t;
isShowing :boolean_t);
+
+simpleroutine PCSetException(clientPort :mach_port_t;
+ message :data_t);
diff --git a/WebKit/mac/Plugins/WebBaseNetscapePluginView.h b/WebKit/mac/Plugins/WebBaseNetscapePluginView.h
index 246fcf1..029a058 100644
--- a/WebKit/mac/Plugins/WebBaseNetscapePluginView.h
+++ b/WebKit/mac/Plugins/WebBaseNetscapePluginView.h
@@ -119,6 +119,7 @@ class WebHaltablePlugin;
- (void)addWindowObservers;
- (void)removeWindowObservers;
+- (BOOL)shouldClipOutPlugin;
- (BOOL)convertFromX:(double)sourceX andY:(double)sourceY space:(NPCoordinateSpace)sourceSpace
toX:(double *)destX andY:(double *)destY space:(NPCoordinateSpace)destSpace;
diff --git a/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm b/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm
index bf8b80b..e93509a 100644
--- a/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm
+++ b/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm
@@ -545,6 +545,22 @@ String WebHaltablePlugin::pluginName() const
return _isHalted;
}
+- (BOOL)superviewsHaveSuperviews
+{
+ NSView *contentView = [[self window] contentView];
+ for (NSView *view = self; view; view = [view superview]) {
+ if (view == contentView)
+ return YES;
+ }
+ return NO;
+}
+
+- (BOOL)shouldClipOutPlugin
+{
+ NSWindow *window = [self window];
+ return !window || [window isMiniaturized] || [NSApp isHidden] || ![self superviewsHaveSuperviews] || [self isHiddenOrHasHiddenAncestor];
+}
+
- (BOOL)hasBeenHalted
{
return _hasBeenHalted;
diff --git a/WebKit/mac/Plugins/WebNetscapePluginView.mm b/WebKit/mac/Plugins/WebNetscapePluginView.mm
index 4a4a435..e96abe8 100644
--- a/WebKit/mac/Plugins/WebNetscapePluginView.mm
+++ b/WebKit/mac/Plugins/WebNetscapePluginView.mm
@@ -197,19 +197,6 @@ typedef struct {
#pragma mark EVENTS
-- (BOOL)superviewsHaveSuperviews
-{
- NSView *contentView = [[self window] contentView];
- NSView *view;
- for (view = self; view != nil; view = [view superview]) {
- if (view == contentView) {
- return YES;
- }
- }
- return NO;
-}
-
-
// The WindowRef created by -[NSWindow windowRef] has a QuickDraw GrafPort that covers
// the entire window frame (or structure region to use the Carbon term) rather then just the window content.
// We can remove this when <rdar://problem/4201099> is fixed.
@@ -329,12 +316,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
// 3) the window is miniaturized or the app is hidden
// 4) we're inside of viewWillMoveToWindow: with a nil window. In this case, superviews may already have nil
// superviews and nil windows and results from convertRect:toView: are incorrect.
- NSWindow *realWindow = [self window];
- if (window.width <= 0 || window.height <= 0 || window.x < -100000
- || realWindow == nil || [realWindow isMiniaturized]
- || [NSApp isHidden]
- || ![self superviewsHaveSuperviews]
- || [self isHiddenOrHasHiddenAncestor]) {
+ if (window.width <= 0 || window.height <= 0 || window.x < -100000 || [self shouldClipOutPlugin]) {
// The following code tries to give plug-ins the same size they will eventually have.
// The specifiedWidth and specifiedHeight variables are used to predict the size that
@@ -351,6 +333,13 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
window.clipRect.bottom = window.clipRect.top;
window.clipRect.left = window.clipRect.right;
+
+ // Core Animation plug-ins need to be updated (with a 0,0,0,0 clipRect) when
+ // moved to a background tab. We don't do this for Core Graphics plug-ins as
+ // older versions of Flash have historical WebKit-specific code that isn't
+ // compatible with this behavior.
+ if (drawingModel == NPDrawingModelCoreAnimation)
+ getNPRect(NSZeroRect, window.clipRect);
} else {
getNPRect(visibleRectInWindow, window.clipRect);
}
diff --git a/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm b/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm
index 5934d7c..eaec807 100644
--- a/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm
+++ b/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm
@@ -1484,15 +1484,15 @@ public:
{
}
- virtual void handleEvent(Event*)
+ virtual void handleEvent(Event* event)
{
Frame* frame = Frame::frameForWidget(this);
if (!frame)
return;
- NSEvent* event = frame->eventHandler()->currentNSEvent();
- if ([event type] == NSMouseMoved)
- [(WebBaseNetscapePluginView *)platformWidget() handleMouseMoved:event];
+ NSEvent* currentNSEvent = frame->eventHandler()->currentNSEvent();
+ if (event->type() == eventNames().mousemoveEvent)
+ [(WebBaseNetscapePluginView *)platformWidget() handleMouseMoved:currentNSEvent];
}
};
diff --git a/WebKit/mac/WebView/WebFrameView.mm b/WebKit/mac/WebView/WebFrameView.mm
index 565e64d..b6b1941 100644
--- a/WebKit/mac/WebView/WebFrameView.mm
+++ b/WebKit/mac/WebView/WebFrameView.mm
@@ -201,7 +201,7 @@ enum {
- (float)_verticalPageScrollDistance
{
float height = [[self _contentView] bounds].size.height;
- return max(height * cFractionToStepWhenPaging, 1.f);
+ return max<float>(height * Scrollbar::minFractionToStepWhenPaging(), height - Scrollbar::maxOverlapBetweenPages());
}
static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCClass, NSArray *supportTypes)
@@ -342,7 +342,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl
[scrollView setHasVerticalScroller:NO];
[scrollView setHasHorizontalScroller:NO];
[scrollView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
- [scrollView setLineScroll:cScrollbarPixelsPerLineStep];
+ [scrollView setLineScroll:Scrollbar::pixelsPerLineStep()];
[self addSubview:scrollView];
// Don't call our overridden version of setNextKeyView here; we need to make the standard NSView
@@ -613,7 +613,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl
- (float)_horizontalPageScrollDistance
{
float width = [[self _contentView] bounds].size.width;
- return max(width * cFractionToStepWhenPaging, 1.f);
+ return max<float>(width * Scrollbar::minFractionToStepWhenPaging(), width - Scrollbar::maxOverlapBetweenPages());
}
- (BOOL)_pageVertically:(BOOL)up
diff --git a/WebKit/mac/WebView/WebPDFDocumentExtras.h b/WebKit/mac/WebView/WebPDFDocumentExtras.h
index 5a33ccf..0dce43e 100644
--- a/WebKit/mac/WebView/WebPDFDocumentExtras.h
+++ b/WebKit/mac/WebView/WebPDFDocumentExtras.h
@@ -23,10 +23,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#import <PDFKit/PDFDocument.h>
+@class PDFDocument;
-@interface PDFDocument (WebPDFDocumentExtras)
-- (NSArray *)_web_allScripts;
-@end
-
-void addWebPDFDocumentExtras(Class);
+NSArray *allScriptsInPDFDocument(PDFDocument *);
diff --git a/WebKit/mac/WebView/WebPDFDocumentExtras.mm b/WebKit/mac/WebView/WebPDFDocumentExtras.mm
index ec580ec..b7043df 100644
--- a/WebKit/mac/WebView/WebPDFDocumentExtras.mm
+++ b/WebKit/mac/WebView/WebPDFDocumentExtras.mm
@@ -68,10 +68,10 @@ static void getAllValuesInPDFNameTree(CGPDFDictionaryRef tree, Vector<CGPDFObjec
appendValuesInPDFNameSubtreeToVector(tree, allValues);
}
-static NSArray *web_PDFDocumentAllScripts(id self, SEL _cmd)
+NSArray *allScriptsInPDFDocument(PDFDocument *document)
{
NSMutableArray *scripts = [NSMutableArray array];
- CGPDFDocumentRef pdfDocument = [self documentRef];
+ CGPDFDocumentRef pdfDocument = [document documentRef];
if (!pdfDocument)
return scripts;
@@ -129,13 +129,3 @@ static NSArray *web_PDFDocumentAllScripts(id self, SEL _cmd)
return scripts;
}
-
-void addWebPDFDocumentExtras(Class pdfDocumentClass)
-{
-#ifndef BUILDING_ON_TIGER
- class_addMethod(pdfDocumentClass, @selector(_web_allScripts), (IMP)web_PDFDocumentAllScripts, "@@:");
-#else
- static struct objc_method_list methodList = { 0, 1, { @selector(_web_allScripts), (char*)"@@:", (IMP)web_PDFDocumentAllScripts } };
- class_addMethods(pdfDocumentClass, &methodList);
-#endif
-}
diff --git a/WebKit/mac/WebView/WebPDFRepresentation.mm b/WebKit/mac/WebView/WebPDFRepresentation.mm
index 924bda8..36449f3 100644
--- a/WebKit/mac/WebView/WebPDFRepresentation.mm
+++ b/WebKit/mac/WebView/WebPDFRepresentation.mm
@@ -70,16 +70,6 @@
return PDFDocumentClass;
}
-+ (void)initialize
-{
- if (self != [WebPDFRepresentation class])
- return;
-
- Class pdfDocumentClass = [self PDFDocumentClass];
- if (pdfDocumentClass)
- addWebPDFDocumentExtras(pdfDocumentClass);
-}
-
- (void)setDataSource:(WebDataSource *)dataSource;
{
}
@@ -136,7 +126,7 @@
PDFDocument *doc = [[[[self class] PDFDocumentClass] alloc] initWithData:data];
[view setPDFDocument:doc];
- NSArray *scripts = [doc _web_allScripts];
+ NSArray *scripts = allScriptsInPDFDocument(doc);
[doc release];
doc = nil;
diff --git a/WebKit/mac/WebView/WebPreferenceKeysPrivate.h b/WebKit/mac/WebView/WebPreferenceKeysPrivate.h
index 7085cec..b8e912e 100644
--- a/WebKit/mac/WebView/WebPreferenceKeysPrivate.h
+++ b/WebKit/mac/WebView/WebPreferenceKeysPrivate.h
@@ -90,6 +90,7 @@
#define WebKitWebGLEnabledPreferenceKey @"WebKitWebGLEnabled"
#define WebKitUsesProxiedOpenPanelPreferenceKey @"WebKitUsesProxiedOpenPanel"
#define WebKitPluginAllowedRunTimePreferenceKey @"WebKitPluginAllowedRunTime"
+#define WebKitFrameSetFlatteningEnabledPreferenceKey @"WebKitFrameSetFlatteningEnabled"
// These are private both because callers should be using the cover methods and because the
// cover methods themselves are private.
diff --git a/WebKit/mac/WebView/WebPreferences.mm b/WebKit/mac/WebView/WebPreferences.mm
index d06cc13..a1176a9 100644
--- a/WebKit/mac/WebView/WebPreferences.mm
+++ b/WebKit/mac/WebView/WebPreferences.mm
@@ -356,6 +356,7 @@ static WebCacheModel cacheModelForMainBundle(void)
[NSNumber numberWithBool:NO], WebKitWebGLEnabledPreferenceKey,
[NSNumber numberWithBool:NO], WebKitUsesProxiedOpenPanelPreferenceKey,
[NSNumber numberWithUnsignedInt:4], WebKitPluginAllowedRunTimePreferenceKey,
+ [NSNumber numberWithBool:NO], WebKitFrameSetFlatteningEnabledPreferenceKey,
nil];
// This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above
@@ -1204,6 +1205,16 @@ static NSString *classIBCreatorID = nil;
return [self _setIntegerValue:allowedRunTime forKey:WebKitPluginAllowedRunTimePreferenceKey];
}
+- (BOOL)isFrameSetFlatteningEnabled
+{
+ return [self _boolValueForKey:WebKitFrameSetFlatteningEnabledPreferenceKey];
+}
+
+- (void)setFrameSetFlatteningEnabled:(BOOL)flag
+{
+ [self _setBoolValue:flag forKey:WebKitFrameSetFlatteningEnabledPreferenceKey];
+}
+
- (void)didRemoveFromWebView
{
ASSERT(_private->numWebViews);
diff --git a/WebKit/mac/WebView/WebPreferencesPrivate.h b/WebKit/mac/WebView/WebPreferencesPrivate.h
index 20c98b2..7c84d8d 100644
--- a/WebKit/mac/WebView/WebPreferencesPrivate.h
+++ b/WebKit/mac/WebView/WebPreferencesPrivate.h
@@ -113,6 +113,9 @@ extern NSString *WebPreferencesRemovedNotification;
- (unsigned)pluginAllowedRunTime;
- (void)setPluginAllowedRunTime:(unsigned)allowedRunTime;
+- (BOOL)isFrameSetFlatteningEnabled;
+- (void)setFrameSetFlatteningEnabled:(BOOL)flag;
+
// zero means do AutoScale
- (float)PDFScaleFactor;
- (void)setPDFScaleFactor:(float)scale;
diff --git a/WebKit/mac/WebView/WebView.mm b/WebKit/mac/WebView/WebView.mm
index e583bb5..4b449de 100644
--- a/WebKit/mac/WebView/WebView.mm
+++ b/WebKit/mac/WebView/WebView.mm
@@ -1334,6 +1334,7 @@ static bool fastDocumentTeardownEnabled()
settings->setPluginAllowedRunTime([preferences pluginAllowedRunTime]);
settings->setWebGLEnabled([preferences webGLEnabled]);
settings->setLoadDeferringEnabled(shouldEnableLoadDeferring());
+ settings->setFrameSetFlatteningEnabled([preferences isFrameSetFlatteningEnabled]);
}
static inline IMP getMethod(id o, SEL s)
diff --git a/WebKit/qt/Api/DerivedSources.pro b/WebKit/qt/Api/DerivedSources.pro
new file mode 100644
index 0000000..8702fde
--- /dev/null
+++ b/WebKit/qt/Api/DerivedSources.pro
@@ -0,0 +1,96 @@
+TEMPLATE = lib
+TARGET = dummy
+
+include(headers.pri)
+
+CONFIG -= debug_and_release
+
+DESTDIR = ../../../include/QtWebKit
+
+QUOTE = ""
+DOUBLE_ESCAPED_QUOTE = ""
+ESCAPE = ""
+win32-msvc*|symbian {
+ ESCAPE = "^"
+} else:win32-g++:isEmpty(QMAKE_SH) {
+ # MinGW's make will run makefile commands using sh, even if make
+ # was run from the Windows shell, if it finds sh in the path.
+ ESCAPE = "^"
+} else {
+ QUOTE = "\'"
+ DOUBLE_ESCAPED_QUOTE = "\\\'"
+}
+
+qtheader_module.target = $${DESTDIR}/QtWebKit
+qtheader_module.depends = $${_PRO_FILE_}
+qtheader_module.commands = echo $${QUOTE}$${LITERAL_HASH}ifndef QT_QTWEBKIT_MODULE_H$${QUOTE} > $${qtheader_module.target} &&
+qtheader_module.commands += echo $${QUOTE}$${LITERAL_HASH}define QT_QTWEBKIT_MODULE_H$${QUOTE} >> $${qtheader_module.target} &&
+qtheader_module.commands += echo $${QUOTE}$${LITERAL_HASH}include $${ESCAPE}<QtNetwork/QtNetwork$${ESCAPE}>$${QUOTE} >> $${qtheader_module.target} &&
+WEBKIT_CLASS_HEADERS = $${LITERAL_DOLLAR}$${LITERAL_DOLLAR}$${LITERAL_DOLLAR}$${LITERAL_DOLLAR}PWD/QtWebKit
+
+regex = ".*\sclass\sQWEBKIT_EXPORT\s(\w+)\s(.*)"
+
+for(HEADER, WEBKIT_API_HEADERS) {
+ qtheader_module.depends += $$HEADER
+ # Quotes need to be escaped once more when placed in eval()
+ eval(qtheader_module.commands += echo $${DOUBLE_ESCAPED_QUOTE}\$${LITERAL_HASH}include \\\"$$basename(HEADER)\\\"$${DOUBLE_ESCAPED_QUOTE} >> $${qtheader_module.target} &&)
+
+ HEADER_NAME = $$basename(HEADER)
+ HEADER_TARGET = $$replace(HEADER_NAME, [^a-zA-Z0-9_], -)
+ HEADER_TARGET = "qtheader-$${HEADER_TARGET}"
+
+ eval($${HEADER_TARGET}.target = $${DESTDIR}/$${HEADER_NAME})
+ eval($${HEADER_TARGET}.depends = $$HEADER)
+ eval($${HEADER_TARGET}.commands = echo $${DOUBLE_ESCAPED_QUOTE}\$${LITERAL_HASH}include \\\"$$HEADER\\\"$${DOUBLE_ESCAPED_QUOTE} > $$eval($${HEADER_TARGET}.target))
+
+ QMAKE_EXTRA_TARGETS += $$HEADER_TARGET
+
+ src_words = $$cat($$HEADER)
+ # Really make sure we're dealing with words
+ src_words = $$split(src_words, " ")
+
+ src = $$join(src_words, $${LITERAL_WHITESPACE})
+ for(ever) {
+ # Looking up by line is faster, so we try that first
+ res = $$find(src_words, "QWEBKIT_EXPORT")
+ isEmpty(res):break()
+
+ # Then do a slow lookup to ensure we're dealing with an exported class
+ res = $$find(src, $$regex)
+ isEmpty(res):break()
+
+ exp = $$replace(src, $$regex, "EXPORTED_CLASS = \1")
+ eval($$exp)
+
+ CLASS_TARGET = "qtheader_$${EXPORTED_CLASS}"
+
+ eval($${CLASS_TARGET}.target = $${DESTDIR}/$${EXPORTED_CLASS})
+ eval($${CLASS_TARGET}.depends = $$eval($${HEADER_TARGET}.target))
+ eval($${CLASS_TARGET}.commands = echo $${DOUBLE_ESCAPED_QUOTE}\$${LITERAL_HASH}include \\\"$$basename(HEADER)\\\"$${DOUBLE_ESCAPED_QUOTE} > $$eval($${CLASS_TARGET}.target))
+
+ QMAKE_EXTRA_TARGETS += $$CLASS_TARGET
+ WEBKIT_CLASS_HEADERS += $${LITERAL_DOLLAR}$${LITERAL_DOLLAR}$${LITERAL_DOLLAR}$${LITERAL_DOLLAR}PWD/$${EXPORTED_CLASS}
+
+ generated_files.depends += $$eval($${CLASS_TARGET}.target)
+ qtheader_pri.depends += $$eval($${CLASS_TARGET}.target)
+
+ # Qt's QRegExp does not support inline non-greedy matching,
+ # so we'll have to work around it by updating the haystack
+ src = $$replace(src, $$regex, "\2")
+ src_words = $$join(src, $${LITERAL_WHITESPACE})
+ }
+}
+
+qtheader_module.commands += echo $${QUOTE}$${LITERAL_HASH}endif // QT_QTWEBKIT_MODULE_H$${QUOTE} >> $${qtheader_module.target}
+QMAKE_EXTRA_TARGETS += qtheader_module
+
+qtheader_pri.target = $${DESTDIR}/classheaders.pri
+qtheader_pri.depends = $${WEBKIT_API_HEADERS} $${_PRO_FILE_}
+qtheader_pri.commands = echo $${QUOTE}WEBKIT_CLASS_HEADERS = $${WEBKIT_CLASS_HEADERS}$${QUOTE} > $${qtheader_pri.target}
+QMAKE_EXTRA_TARGETS += qtheader_pri
+
+generated_files.depends += $${qtheader_module.target} $${qtheader_pri.target}
+QMAKE_EXTRA_TARGETS += generated_files
+
+
+
diff --git a/WebKit/qt/Api/qgraphicswebview.cpp b/WebKit/qt/Api/qgraphicswebview.cpp
index 8d4f3ba..b323598 100644
--- a/WebKit/qt/Api/qgraphicswebview.cpp
+++ b/WebKit/qt/Api/qgraphicswebview.cpp
@@ -27,6 +27,7 @@
#include "qwebpage_p.h"
#include "QWebPageClient.h"
#include <FrameView.h>
+#include <QtCore/qmetaobject.h>
#include <QtCore/qsharedpointer.h>
#include <QtCore/qtimer.h>
#include <QtGui/qapplication.h>
@@ -78,13 +79,14 @@ public:
, page(0)
#if USE(ACCELERATED_COMPOSITING)
, rootGraphicsLayer(0)
- , shouldSync(true)
+ , shouldSync(false)
#endif
{
#if USE(ACCELERATED_COMPOSITING)
// the overlay and stays alive for the lifetime of
// this QGraphicsWebView as the scrollbars are needed when there's no compositing
q->setFlag(QGraphicsItem::ItemUsesExtendedStyleOption);
+ syncMetaMethod = q->metaObject()->method(q->metaObject()->indexOfMethod("syncLayers()"));
#endif
}
@@ -131,6 +133,9 @@ public:
// compositor telling us to do so. We'll get that call from ChromeClientQt
bool shouldSync;
+ // we have to flush quite often, so we use a meta-method instead of QTimer::singleShot for putting the event in the queue
+ QMetaMethod syncMetaMethod;
+
// we need to put the root graphics layer behind the overlay (which contains the scrollbar)
enum { RootGraphicsLayerZValue, OverlayZValue };
#endif
@@ -178,7 +183,7 @@ void QGraphicsWebViewPrivate::markForSync(bool scheduleSync)
{
shouldSync = true;
if (scheduleSync)
- QTimer::singleShot(0, q, SLOT(syncLayers()));
+ syncMetaMethod.invoke(q, Qt::QueuedConnection);
}
void QGraphicsWebViewPrivate::updateCompositingScrollPosition()
@@ -224,6 +229,7 @@ void QGraphicsWebViewPrivate::update(const QRect & dirtyRect)
#if USE(ACCELERATED_COMPOSITING)
if (overlay)
overlay->update(QRectF(dirtyRect));
+ syncLayers();
#endif
}
@@ -442,7 +448,6 @@ void QGraphicsWebView::paint(QPainter* painter, const QStyleOptionGraphicsItem*
{
#if USE(ACCELERATED_COMPOSITING)
page()->mainFrame()->render(painter, d->overlay ? QWebFrame::ContentsLayer : QWebFrame::AllLayers, option->exposedRect.toAlignedRect());
- d->syncLayers();
#else
page()->mainFrame()->render(painter, QWebFrame::AllLayers, option->exposedRect.toRect());
#endif
diff --git a/WebKit/qt/Api/qwebelement.cpp b/WebKit/qt/Api/qwebelement.cpp
index 441bec7..9d4d0d0 100644
--- a/WebKit/qt/Api/qwebelement.cpp
+++ b/WebKit/qt/Api/qwebelement.cpp
@@ -38,7 +38,6 @@
#include "NodeList.h"
#include "PropertyNameArray.h"
#include "RenderImage.h"
-#include "ScriptFunctionCall.h"
#include "StaticNodeList.h"
#include "qt_runtime.h"
#include "qwebframe.h"
diff --git a/WebKit/qt/Api/qwebframe.cpp b/WebKit/qt/Api/qwebframe.cpp
index aeb7a22..4c1f318 100644
--- a/WebKit/qt/Api/qwebframe.cpp
+++ b/WebKit/qt/Api/qwebframe.cpp
@@ -220,6 +220,19 @@ QString QWEBKIT_EXPORT qt_drt_counterValueForElementById(QWebFrame* qFrame, cons
return QString();
}
+int QWEBKIT_EXPORT qt_drt_pageNumberForElementById(QWebFrame* qFrame, const QString& id, float width, float height)
+{
+ Frame* frame = QWebFramePrivate::core(qFrame);
+ if (!frame)
+ return -1;
+
+ Element* element = frame->document()->getElementById(AtomicString(id));
+ if (!element)
+ return -1;
+
+ return PrintContext::pageNumberForElement(element, FloatSize(width, height));
+}
+
// Suspend active DOM objects in this frame.
void QWEBKIT_EXPORT qt_suspendActiveDOMObjects(QWebFrame* qFrame)
{
diff --git a/WebKit/qt/Api/qwebpage.cpp b/WebKit/qt/Api/qwebpage.cpp
index ea2401b..f661918 100644
--- a/WebKit/qt/Api/qwebpage.cpp
+++ b/WebKit/qt/Api/qwebpage.cpp
@@ -146,6 +146,11 @@ void QWEBKIT_EXPORT qt_drt_run(bool b)
QWebPagePrivate::drtRun = b;
}
+void QWEBKIT_EXPORT qt_drt_setFrameSetFlatteningEnabled(QWebPage* page, bool enabled)
+{
+ QWebPagePrivate::core(page)->settings()->setFrameSetFlatteningEnabled(enabled);
+}
+
void QWEBKIT_EXPORT qt_webpage_setGroupName(QWebPage* page, const QString& groupName)
{
page->handle()->page->setGroupName(groupName);
@@ -444,6 +449,11 @@ QWebPagePrivate::~QWebPagePrivate()
delete page;
}
+WebCore::Page* QWebPagePrivate::core(QWebPage* page)
+{
+ return page->d->page;
+}
+
bool QWebPagePrivate::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
{
if (insideOpenCall
@@ -1945,6 +1955,8 @@ bool QWebPage::shouldInterruptJavaScript()
If the view associated with the web page is a QWebView object, then the default implementation forwards
the request to QWebView's createWindow() function; otherwise it returns a null pointer.
+ If \a type is WebModalDialog, the application must call setWindowModality(Qt::ApplicationModal) on the new window.
+
\sa acceptNavigationRequest()
*/
QWebPage *QWebPage::createWindow(WebWindowType type)
diff --git a/WebKit/qt/Api/qwebpage_p.h b/WebKit/qt/Api/qwebpage_p.h
index dbc981e..15ddfb2 100644
--- a/WebKit/qt/Api/qwebpage_p.h
+++ b/WebKit/qt/Api/qwebpage_p.h
@@ -62,6 +62,9 @@ class QWebPagePrivate {
public:
QWebPagePrivate(QWebPage*);
~QWebPagePrivate();
+
+ static WebCore::Page* core(QWebPage*);
+
void createMainFrame();
#ifndef QT_NO_CONTEXTMENU
QMenu* createContextMenu(const WebCore::ContextMenu* webcoreMenu, const QList<WebCore::ContextMenuItem>* items, QBitArray* visitedWebActions);
diff --git a/WebKit/qt/Api/qwebview.cpp b/WebKit/qt/Api/qwebview.cpp
index b5a5a90..79c16c7 100644
--- a/WebKit/qt/Api/qwebview.cpp
+++ b/WebKit/qt/Api/qwebview.cpp
@@ -60,96 +60,141 @@ void QWebViewPrivate::_q_pageDestroyed()
#ifdef Q_WS_MAEMO_5
#include "qabstractkineticscroller.h"
+#include "qapplication.h"
-class QWebViewKineticScroller : public QAbstractKineticScroller {
+// QCoreApplication::sendSpontaneousEvent() is private, hence this friend wrapper
+bool qt_sendSpontaneousEvent(QObject* receiver, QEvent* ev)
+{
+ return QCoreApplication::sendSpontaneousEvent(receiver, ev);
+}
+
+class QWebViewKineticScroller : public QObject, public QAbstractKineticScroller {
public:
- QWebViewKineticScroller() : QAbstractKineticScroller() {}
- // remember the frame where the button was pressed
+ QWebViewKineticScroller()
+ : QObject()
+ , QAbstractKineticScroller()
+ , m_view(0)
+ , m_ignoreEvents(false)
+ {
+ }
+
+ void setWidget(QWebView* widget)
+ {
+ if (m_view) {
+ m_view->removeEventFilter(this);
+ QWebFrame* frame = m_view->page()->mainFrame();
+ frame->setScrollBarPolicy(Qt::Vertical, m_oldVerticalScrollBarPolicy);
+ frame->setScrollBarPolicy(Qt::Horizontal, m_oldHorizontalScrollBarPolicy);
+ }
+
+ m_view = widget;
+ setParent(m_view);
+ if (m_view) {
+ QWebFrame* frame = m_view->page()->mainFrame();
+ m_oldHorizontalScrollBarPolicy = frame->scrollBarPolicy(Qt::Horizontal);
+ m_oldVerticalScrollBarPolicy = frame->scrollBarPolicy(Qt::Vertical);
+ frame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
+ frame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
+ m_view->installEventFilter(this);
+ }
+ }
+
+protected:
bool eventFilter(QObject* o, QEvent* ev)
{
+ if (!o || m_view != o || m_ignoreEvents || !m_view->isEnabled())
+ return QObject::eventFilter(o, ev);
+
+ bool res = false;
+
switch (ev->type()) {
case QEvent::MouseButtonPress: {
+ // remember the frame where the button was pressed
QWebFrame* hitFrame = scrollingFrameAt(static_cast<QMouseEvent*>(ev)->pos());
if (hitFrame)
m_frame = hitFrame;
- break;
+ // fall through
}
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ res = handleMouseEvent(static_cast<QMouseEvent*>(ev));
+ break;
default:
break;
}
- return QAbstractKineticScroller::eventFilter(o, ev);
+ return res ? true : QObject::eventFilter(o, ev);
}
-protected:
- QWebFrame* currentFrame() const
+ void cancelLeftMouseButtonPress(const QPoint& /* globalPressPos */)
{
- if (!m_frame.isNull())
- return m_frame.data();
-
- QWebView* view = static_cast<QWebView*>(widget());
- QWebFrame* frame = view->page()->mainFrame();
- return frame;
+ QMouseEvent cmem(QEvent::MouseMove, QPoint(-INT_MAX, -INT_MAX), Qt::LeftButton, QApplication::mouseButtons() | Qt::LeftButton, QApplication::keyboardModifiers());
+ sendEvent(m_view, &cmem);
+ QMouseEvent cmer(QEvent::MouseButtonRelease, QPoint(-INT_MAX, -INT_MAX), Qt::LeftButton, QApplication::mouseButtons() & ~Qt::LeftButton, QApplication::keyboardModifiers());
+ sendEvent(m_view, &cmer);
}
- // Returns the innermost frame at the given position that can scroll.
- QWebFrame* scrollingFrameAt(const QPoint& pos) const
+ QWebFrame* currentFrame() const
{
- QWebView* view = static_cast<QWebView*>(widget());
- QWebFrame* mainFrame = view->page()->mainFrame();
- QWebFrame* hitFrame = mainFrame->hitTestContent(pos).frame();
- QSize range = hitFrame->contentsSize() - hitFrame->geometry().size();
+ if (m_frame)
+ return m_frame;
- while (hitFrame && range.width() <= 1 && range.height() <= 1)
- hitFrame = hitFrame->parentFrame();
+ if (m_view)
+ return m_view->page()->mainFrame();
- return hitFrame;
+ return 0;
}
- void attachToWidget()
+ // Returns the innermost frame at the given position that can scroll.
+ QWebFrame* scrollingFrameAt(const QPoint& pos) const
{
- QWebView* view = static_cast<QWebView*>(widget());
- QWebFrame* mainFrame = view->page()->mainFrame();
- m_oldHorizontalScrollBarPolicy = mainFrame->scrollBarPolicy(Qt::Horizontal);
- m_oldVerticalScrollBarPolicy = mainFrame->scrollBarPolicy(Qt::Vertical);
- mainFrame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
- mainFrame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
- view->installEventFilter(this);
- }
+ QWebFrame* hitFrame = 0;
+ if (m_view) {
+ QWebFrame* frame = m_view->page()->mainFrame();
+ hitFrame = frame->hitTestContent(pos).frame();
+ QSize range = hitFrame->contentsSize() - hitFrame->geometry().size();
- void removeFromWidget()
- {
- QWebView* view = static_cast<QWebView*>(widget());
- view->removeEventFilter(this);
- QWebFrame* mainFrame = view->page()->mainFrame();
- mainFrame->setScrollBarPolicy(Qt::Vertical, m_oldVerticalScrollBarPolicy);
- mainFrame->setScrollBarPolicy(Qt::Horizontal, m_oldHorizontalScrollBarPolicy);
+ while (hitFrame && range.width() <= 1 && range.height() <= 1)
+ hitFrame = hitFrame->parentFrame();
+
+ return hitFrame;
+ }
}
- QRect positionRange() const
+ QPoint maximumScrollPosition() const
{
- QRect r;
QWebFrame* frame = currentFrame();
- r.setSize(frame->contentsSize() - frame->geometry().size());
- return r;
+ QSize s = frame ? frame->contentsSize() - frame->geometry().size() : QSize(0, 0);
+ return QPoint(qMax(0, s.width()), qMax(0, s.height()));
}
- QPoint position() const
+ QPoint scrollPosition() const
{
QWebFrame* frame = currentFrame();
- return frame->scrollPosition();
+ return frame ? frame->scrollPosition() : QPoint();
}
QSize viewportSize() const
{
- return static_cast<QWebView*>(widget())->page()->viewportSize();
+ return m_view ? m_view->page()->viewportSize() : QSize();
}
- void setPosition(const QPoint& point, const QPoint& /* overShootDelta */)
+ void setScrollPosition(const QPoint& point, const QPoint& /* overShootDelta */)
{
QWebFrame* frame = currentFrame();
- frame->setScrollPosition(point);
+ if (frame)
+ frame->setScrollPosition(point);
+ }
+
+ void sendEvent(QWidget* w, QEvent* ev)
+ {
+ m_ignoreEvents = true;
+ qt_sendSpontaneousEvent(w, ev);
+ m_ignoreEvents = false;
}
+ QWebView* m_view;
+ bool m_ignoreEvents;
QPointer<QWebFrame> m_frame;
Qt::ScrollBarPolicy m_oldVerticalScrollBarPolicy;
Qt::ScrollBarPolicy m_oldHorizontalScrollBarPolicy;
@@ -259,7 +304,7 @@ QWebView::QWebView(QWidget *parent)
#endif
#if defined(Q_WS_MAEMO_5)
QAbstractKineticScroller* scroller = new QWebViewKineticScroller();
- scroller->setWidget(this);
+ static_cast<QWebViewKineticScroller*>(scroller)->setWidget(this);
setProperty("kineticScroller", QVariant::fromValue(scroller));
#endif
setAcceptDrops(true);
diff --git a/WebKit/qt/ChangeLog b/WebKit/qt/ChangeLog
index e63ee86..e0d1b28 100644
--- a/WebKit/qt/ChangeLog
+++ b/WebKit/qt/ChangeLog
@@ -1,3 +1,222 @@
+2010-02-12 Diego Gonzalez <diego.gonzalez@openbossa.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Qt DRT now dump the frame loader callbacks when LayoutTestController()
+ method is called.
+
+ LayoutTests:
+ http/tests/security/mixedContent/data-url-script-in-iframe.html
+ http/tests/security/mixedContent/empty-url-plugin-in-frame.html
+ http/tests/security/mixedContent/insecure-css-in-iframe.html
+ http/tests/security/mixedContent/insecure-iframe-in-iframe.html
+ http/tests/security/mixedContent/insecure-image-in-iframe.html
+ http/tests/security/mixedContent/insecure-plugin-in-iframe.html
+ http/tests/security/mixedContent/insecure-script-in-iframe.html
+ http/tests/security/mixedContent/redirect-http-to-https-script-in-iframe.html
+ http/tests/security/mixedContent/redirect-https-to-http-script-in-iframe.html
+
+ [Qt] Make possible Qt DRT dump frame load callbacks
+ https://bugs.webkit.org/show_bug.cgi?id=34702
+
+ * WebCoreSupport/FrameLoaderClientQt.cpp:
+ (WebCore::FrameLoaderClientQt::didDisplayInsecureContent):
+ (WebCore::FrameLoaderClientQt::didRunInsecureContent):
+
+2010-02-10 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ [Qt] Make qtlauncher and qgvlauncher use the generated headers
+ path to make sure they are correctly generated.
+
+ * tests/tests.pri:
+
+2010-02-10 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ [Qt] Ensure relative paths in generated .pri files to ensure that
+ a source package with pre-generated derived sources can be compiled.
+
+ - Re-add a separate headers.pri file for WEBKIT_API_HEADERS
+ - Rename the generated headers.pri to classheaders.pri to avoid
+ confusion with the one generated by synqt since they don't have the
+ same content.
+ - Remove private headers list variable from classheaders.pri
+ - Use $$PWD in classheaders.pri
+ - Remove classheaders.pri from the installed files
+
+ * Api/DerivedSources.pro:
+
+2010-02-10 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ [Qt] Minor fixes on QtWebKit headers generation.
+
+ - Adds QtWebKit to the generated headers destination path
+ - Improve compatibility with MinGW
+
+ * Api/DerivedSources.pro:
+
+2010-02-09 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by nobody, build fix.
+
+ [Qt] Fix standalone build with MinGW.
+
+ * tests/qwebelement/tst_qwebelement.cpp:
+ * tests/tests.pri:
+
+2010-02-10 Diego Gonzalez <diego.gonzalez@openbossa.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Implement pageNumberForElementById() method in Qt DRT LayoutTestController,
+ to make Qt DRT able to get page number.
+
+ LayoutTests:
+ printing/page-break-always.html
+ printing/pageNumerForElementById.html
+ printing/css2.1/page-break-before-000.html
+ printing/css2.1/page-break-after-000.html
+ printing/css2.1/page-break-after-004.html
+ printing/css2.1/page-break-before-001.html
+ printing/css2.1/page-break-after-001.html
+ printing/css2.1/page-break-after-002.html
+ printing/css2.1/page-break-before-002.html
+ printing/css2.1/page-break-inside-000.html
+
+ [Qt] Make possible Qt DRT get a page number for element by ID
+ https://bugs.webkit.org/show_bug.cgi?id=34777
+
+ * Api/qwebframe.cpp:
+ (qt_drt_pageNumberForElementById):
+
+2010-02-09 Yael Aharon <yael.aharon@nokia.com>
+
+ Reviewed by Adam Barth.
+
+ [Qt] Unit test for window.runModalDialog
+ https://bugs.webkit.org/show_bug.cgi?id=34755
+
+ * tests/qwebpage/tst_qwebpage.cpp:
+ (TestModalPage::TestModalPage):
+ (TestModalPage::createWindow):
+ (tst_QWebPage::showModalDialog):
+
+2010-02-09 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Sync with API changes in Maemo 5 kinetic scrolling
+
+ https://bugs.webkit.org/show_bug.cgi?id=34747
+
+ This is a forward-port of http://qt.gitorious.org/+qt-developers/qt/x11-maemo/commit/08497561
+
+ * Api/qwebview.cpp:
+ (qt_sendSpontaneousEvent):
+ (QWebViewKineticScroller::QWebViewKineticScroller):
+ (QWebViewKineticScroller::setWidget):
+ (QWebViewKineticScroller::eventFilter):
+ (QWebViewKineticScroller::cancelLeftMouseButtonPress):
+ (QWebViewKineticScroller::currentFrame):
+ (QWebViewKineticScroller::scrollingFrameAt):
+ (QWebViewKineticScroller::maximumScrollPosition):
+ (QWebViewKineticScroller::scrollPosition):
+ (QWebViewKineticScroller::viewportSize):
+ (QWebViewKineticScroller::setScrollPosition):
+ (QWebViewKineticScroller::sendEvent):
+ (QWebView::QWebView):
+
+2010-02-09 Yael Aharon <yael.aharon@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Webkit in Qt does not have window.showModalDialog
+ https://bugs.webkit.org/show_bug.cgi?id=25585
+
+ Create a new eventloop when runModal() is called.
+ Added comemnt in QWebPage::createWindow that the application is responsible
+ for setting the modality of the appropriate window.
+
+ * Api/qwebpage.cpp:
+ * WebCoreSupport/ChromeClientQt.cpp:
+ (WebCore::ChromeClientQt::ChromeClientQt):
+ (WebCore::ChromeClientQt::~ChromeClientQt):
+ (WebCore::ChromeClientQt::canRunModal):
+ (WebCore::ChromeClientQt::runModal):
+ * WebCoreSupport/ChromeClientQt.h:
+
+2010-01-19 Kenneth Rohde Christiansen <kenneth@webkit.org>
+
+ Reviewed by Dave Hyatt.
+
+ Implement flattening of framesets
+ https://bugs.webkit.org/show_bug.cgi?id=32717
+
+ Privately export the setFrameSetFlatteningEnabled setting for
+ use with the Qt DRT.
+
+ * Api/qwebpage.cpp:
+ (qt_drt_setFrameSetFlatteningEnabled):
+ (QWebPagePrivate::core):
+ * Api/qwebpage_p.h:
+
+2010-02-05 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ [Qt] Fix build on Windows
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ DerivedSources for our API headers failed on Windows,
+ due to Windows not accepting ; as a command separator,
+ not needing quotes for echo, and needing < and > escaped.
+
+ We now detect Windows and set these quote markers and
+ escape markers accordingly, as well as use && for separating
+ individual commands.
+
+ * Api/DerivedSources.pro:
+
+2010-02-05 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Remove unused inmport of ScriptFunctionCall.h
+
+ https://bugs.webkit.org/show_bug.cgi?id=33592
+
+ * Api/qwebelement.cpp:
+
+2010-02-05 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Generate convenience headers (QWebView, etc) using qmake
+
+ In Qt this is done using syncqt, but we use a pro-file instead
+ that generates makefile-rules for each of the extra headers.
+
+ These extra headers are installed alongside the normal headers.
+
+ * Api/DerivedSources.pro: Added. List of headers + pro file magic
+ * Api/headers.pri: Removed, list of headers is now in the above file
+
+2010-02-04 No'am Rosenthal <noam.rosenthal@nokia.com>
+
+ Reviewed by Ariya Hidayat.
+
+ [Qt] Tuning and optimizations to GraphicsLayerQt. Mainly reduced usage
+ of QTimer::singleShot, and moved syncLayers() from paint() to update()
+ https://bugs.webkit.org/show_bug.cgi?id=34062
+
+ * Api/qgraphicswebview.cpp:
+ (QGraphicsWebViewPrivate::update): Moved the sync operation to update
+ (QGraphicsWebView::paint): Moved the sync operation to update
+
2010-02-03 Andras Becsi <abecsi@webkit.org>
Unreviewed build fix.
diff --git a/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp b/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp
index f1e6a86..893a1b7 100644
--- a/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp
+++ b/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp
@@ -44,6 +44,7 @@
#include "SecurityOrigin.h"
#include <qdebug.h>
+#include <qeventloop.h>
#include <qtextdocument.h>
#include <qtooltip.h>
@@ -62,13 +63,15 @@ namespace WebCore {
ChromeClientQt::ChromeClientQt(QWebPage* webPage)
: m_webPage(webPage)
+ , m_eventLoop(0)
{
toolBarsVisible = statusBarVisible = menuBarVisible = true;
}
ChromeClientQt::~ChromeClientQt()
{
-
+ if (m_eventLoop)
+ m_eventLoop->exit();
}
void ChromeClientQt::setWindowRect(const FloatRect& rect)
@@ -173,14 +176,16 @@ void ChromeClientQt::show()
bool ChromeClientQt::canRunModal()
{
- notImplemented();
- return false;
+ return true;
}
void ChromeClientQt::runModal()
{
- notImplemented();
+ m_eventLoop = new QEventLoop();
+ QEventLoop* eventLoop = m_eventLoop;
+ m_eventLoop->exec();
+ delete eventLoop;
}
diff --git a/WebKit/qt/WebCoreSupport/ChromeClientQt.h b/WebKit/qt/WebCoreSupport/ChromeClientQt.h
index 7699349..6b3017d 100644
--- a/WebKit/qt/WebCoreSupport/ChromeClientQt.h
+++ b/WebKit/qt/WebCoreSupport/ChromeClientQt.h
@@ -34,6 +34,7 @@
#include "KURL.h"
#include "PlatformString.h"
+class QEventLoop;
class QWebPage;
namespace WebCore {
@@ -158,6 +159,7 @@ namespace WebCore {
bool toolBarsVisible;
bool statusBarVisible;
bool menuBarVisible;
+ QEventLoop* m_eventLoop;
};
}
diff --git a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
index 760e37e..16a6faa 100644
--- a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
+++ b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
@@ -672,11 +672,17 @@ void FrameLoaderClientQt::dispatchDidChangeBackForwardIndex() const
void FrameLoaderClientQt::didDisplayInsecureContent()
{
+ if (dumpFrameLoaderCallbacks)
+ printf("didDisplayInsecureContent\n");
+
notImplemented();
}
void FrameLoaderClientQt::didRunInsecureContent(WebCore::SecurityOrigin*)
{
+ if (dumpFrameLoaderCallbacks)
+ printf("didRunInsecureContent\n");
+
notImplemented();
}
diff --git a/WebKit/qt/tests/qwebelement/tst_qwebelement.cpp b/WebKit/qt/tests/qwebelement/tst_qwebelement.cpp
index dde65cf..8db0ec3 100644
--- a/WebKit/qt/tests/qwebelement/tst_qwebelement.cpp
+++ b/WebKit/qt/tests/qwebelement/tst_qwebelement.cpp
@@ -18,13 +18,13 @@
*/
-#include <../util.h>
#include <QtTest/QtTest>
#include <qwebpage.h>
#include <qwidget.h>
#include <qwebview.h>
#include <qwebframe.h>
#include <qwebelement.h>
+#include <util.h>
//TESTED_CLASS=
//TESTED_FILES=
diff --git a/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
index f48fb73..ba7a87e 100644
--- a/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
+++ b/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
@@ -110,6 +110,7 @@ private slots:
void originatingObjectInNetworkRequests();
void testJSPrompt();
+ void showModalDialog();
private:
QWebView* m_view;
@@ -1828,5 +1829,26 @@ void tst_QWebPage::testJSPrompt()
QVERIFY(res);
}
+class TestModalPage : public QWebPage
+{
+ Q_OBJECT
+public:
+ TestModalPage(QObject* parent = 0) : QWebPage(parent) {
+ }
+ virtual QWebPage* createWindow(WebWindowType) {
+ QWebPage* page = new TestModalPage();
+ connect(page, SIGNAL(windowCloseRequested()), page, SLOT(deleteLater()));
+ return page;
+ }
+};
+
+void tst_QWebPage::showModalDialog()
+{
+ TestModalPage page;
+ page.mainFrame()->setHtml(QString("<html></html>"));
+ QString res = page.mainFrame()->evaluateJavaScript("window.showModalDialog('javascript:window.returnValue=dialogArguments; window.close();', 'This is a test');").toString();
+ QCOMPARE(res, QString("This is a test"));
+}
+
QTEST_MAIN(tst_QWebPage)
#include "tst_qwebpage.moc"
diff --git a/WebKit/qt/tests/tests.pri b/WebKit/qt/tests/tests.pri
index c3d7755..187950a 100644
--- a/WebKit/qt/tests/tests.pri
+++ b/WebKit/qt/tests/tests.pri
@@ -3,6 +3,9 @@ CONFIG -= app_bundle
TARGET = tst_$$TARGET
SOURCES += $$_PRO_FILE_PWD_/$${TARGET}.cpp
+INCLUDEPATH += \
+ $$PWD \
+ $$PWD/../Api
exists($$_PRO_FILE_PWD_/$${TARGET}.qrc):RESOURCES += $$_PRO_FILE_PWD_/$${TARGET}.qrc
diff --git a/WebKit/win/AccessibleBase.cpp b/WebKit/win/AccessibleBase.cpp
index 0704771..3e8306f 100644
--- a/WebKit/win/AccessibleBase.cpp
+++ b/WebKit/win/AccessibleBase.cpp
@@ -382,10 +382,10 @@ HRESULT STDMETHODCALLTYPE AccessibleBase::get_accKeyboardShortcut(VARIANT vChild
HRESULT STDMETHODCALLTYPE AccessibleBase::accSelect(long selectionFlags, VARIANT vChild)
{
// According to MSDN, these combinations are invalid.
- if (((selectionFlags & (SELFLAG_ADDSELECTION | SELFLAG_REMOVESELECTION)) == (SELFLAG_ADDSELECTION | SELFLAG_REMOVESELECTION)) ||
- ((selectionFlags & (SELFLAG_ADDSELECTION | SELFLAG_TAKESELECTION)) == (SELFLAG_ADDSELECTION | SELFLAG_TAKESELECTION)) ||
- ((selectionFlags & (SELFLAG_REMOVESELECTION | SELFLAG_TAKESELECTION)) == (SELFLAG_REMOVESELECTION | SELFLAG_TAKESELECTION)) ||
- ((selectionFlags & (SELFLAG_EXTENDSELECTION | SELFLAG_TAKESELECTION)) == (SELFLAG_REMOVESELECTION | SELFLAG_TAKESELECTION)))
+ if (((selectionFlags & (SELFLAG_ADDSELECTION | SELFLAG_REMOVESELECTION)) == (SELFLAG_ADDSELECTION | SELFLAG_REMOVESELECTION))
+ || ((selectionFlags & (SELFLAG_ADDSELECTION | SELFLAG_TAKESELECTION)) == (SELFLAG_ADDSELECTION | SELFLAG_TAKESELECTION))
+ || ((selectionFlags & (SELFLAG_REMOVESELECTION | SELFLAG_TAKESELECTION)) == (SELFLAG_REMOVESELECTION | SELFLAG_TAKESELECTION))
+ || ((selectionFlags & (SELFLAG_EXTENDSELECTION | SELFLAG_TAKESELECTION)) == (SELFLAG_EXTENDSELECTION | SELFLAG_TAKESELECTION)))
return E_INVALIDARG;
AccessibilityObject* childObject;
@@ -406,15 +406,19 @@ HRESULT STDMETHODCALLTYPE AccessibleBase::accSelect(long selectionFlags, VARIANT
Vector<RefPtr<AccessibilityObject> > selectedChildren(1);
selectedChildren[0] = childObject;
static_cast<AccessibilityListBox*>(parentObject)->setSelectedChildren(selectedChildren);
- } else if (parentObject->isMenuListPopup())
+ } else { // any element may be selectable by virtue of it having the aria-selected property
+ ASSERT(!parentObject->isMultiSelectable());
childObject->setSelected(true);
- else
- return E_INVALIDARG;
+ }
}
- // MSDN says that ADD, REMOVE, and EXTENDSELECTION are invalid for
+ // MSDN says that ADD, REMOVE, and EXTENDSELECTION with no other flags are invalid for
// single-select.
- if (!parentObject->isMultiSelectable())
+ const long allSELFLAGs = SELFLAG_TAKEFOCUS | SELFLAG_TAKESELECTION | SELFLAG_EXTENDSELECTION | SELFLAG_ADDSELECTION | SELFLAG_REMOVESELECTION;
+ if (!parentObject->isMultiSelectable()
+ && (((selectionFlags & allSELFLAGs) == SELFLAG_ADDSELECTION)
+ || ((selectionFlags & allSELFLAGs) == SELFLAG_REMOVESELECTION)
+ || ((selectionFlags & allSELFLAGs) == SELFLAG_EXTENDSELECTION)))
return E_INVALIDARG;
if (selectionFlags & SELFLAG_ADDSELECTION)
diff --git a/WebKit/win/ChangeLog b/WebKit/win/ChangeLog
index 36d3144..feb22a1 100644
--- a/WebKit/win/ChangeLog
+++ b/WebKit/win/ChangeLog
@@ -1,3 +1,113 @@
+2010-02-10 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Support frameset flattening
+ https://bugs.webkit.org/show_bug.cgi?id=32717
+
+ Add support for enabling/disabling FrameSet Flattening on the Windows port.
+
+ * Interfaces/IWebPreferencesPrivate.idl:
+ * WebPreferenceKeysPrivate.h:
+ * WebPreferences.cpp:
+ (WebPreferences::initializeDefaultSettings):
+ (WebPreferences::isFrameSetFlatteningEnabled):
+ (WebPreferences::setFrameSetFlatteningEnabled):
+ * WebPreferences.h:
+ * WebView.cpp:
+ (WebView::notifyPreferencesChanged):
+
+2010-02-10 Adam Roben <aroben@apple.com>
+
+ Remove unnecessary #include of shfolder.h
+
+ shfolder.h has been deprecated in newer versions of the Windows SDK.
+
+ Fixes <http://webkit.org/b/34803> WebPreferences.cpp fails to compile
+ under VS2010 RC due to #include of shfolder.h.
+
+ Reviewed by Darin Adler.
+
+ * WebPreferences.cpp: Removed #include.
+
+2010-02-08 Charlie Reis <creis@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ onbeforeunload not called at window close + frame or iframe focused
+ https://bugs.webkit.org/show_bug.cgi?id=27481
+
+ Chromium and WebKit on Windows will now fire beforeunload handlers
+ even if an inner frame is focused.
+
+ Layout tests aren't able to test this bug, since it requires closing
+ the actual browser window, not calling window.close(). Instead,
+ test with WebCore/manual-tests/onbeforeunload-focused-iframe.html.
+
+ * WebView.cpp:
+ (WebView::shouldClose):
+
+2010-02-08 Brent Fulgham <bfulgham@webkit.org>
+
+ Reviewed by Adam Roben.
+
+ Include header position in World Transform used for plugin positioning.
+ https://bugs.webkit.org/show_bug.cgi?id=34709
+
+ * WebFrame.cpp:
+ (WebFrame::spoolPage): Correct WinCairo plugin print positioning to
+ account for header size. Existing code ignored this, causing
+ plugins to overlay other elements.
+
+2010-02-04 Alice Liu <alice.liu@apple.com>
+
+ Reviewed by Jon Honeycutt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34612 " MSAA: accSelect returns error
+ codes for most elements that arent listbox or menupopup related"
+ <rdar://problem/7436861>
+
+ * AccessibleBase.cpp:
+ (AccessibleBase::accSelect):
+ - Stop sending E_INVALIDARG for elements that request TAKE_SELECTION that
+ aren't beneath listboxes or menupopups. This was too restrictive since
+ any element can be selectable.
+ - Correct the misinterpretation of MSDN's stipulation of situations involving
+ adding, removing, and extending selection on single-select elements
+
+2010-02-04 Brent Fulgham <bfulgham@webkit.org>
+
+ Reviewed by Adam Roben.
+
+ Properly handle margin settings when printing Plugins in WinCairo.
+ https://bugs.webkit.org/show_bug.cgi?id=34613
+
+ * WebFrame.cpp:
+ (WebFrame::spoolPage): Adjust the GraphicsContext passed to the
+ paintContents method so that the World Transform is properly
+ positioned to account for margin settings at the time that
+ PluginViewWin.cpp processes the drawing operations.
+
+2010-02-04 Brent Fulgham <bfulgham@webkit.org>
+
+ Reviewed by Adam Roben.
+
+ Properly handle margin settings in WinCairo.
+ https://bugs.webkit.org/show_bug.cgi?id=34545
+
+ * WebFrame.cpp:
+ (scaleFactor): Require the margin information as an input
+ parameter, and use them when computing the scaling factor.
+ (WebFrame::drawHeader): Pass margin size to scaleFactor.
+ (WebFrame::drawFooter): Pass margin size to scaleFactor.
+ (WebFrame::spoolPage):
+ 1. Pass margin size to scaleFactor.
+ 2. Recognize that the return value of printerMarginRect is
+ already in device units, and therefore scale it so that
+ the Cairo drawing is correct.
+ 3. Remove scaling call for margins in GDI code, as it is
+ already in scaled units.
+
2010-02-03 Brian Weinstein <bweinstein@apple.com>
Reviewed by Steve Falkenburg.
diff --git a/WebKit/win/Interfaces/IWebPreferencesPrivate.idl b/WebKit/win/Interfaces/IWebPreferencesPrivate.idl
index 1293fb8..613a53d 100644
--- a/WebKit/win/Interfaces/IWebPreferencesPrivate.idl
+++ b/WebKit/win/Interfaces/IWebPreferencesPrivate.idl
@@ -79,6 +79,9 @@ interface IWebPreferencesPrivate : IUnknown
HRESULT isXSSAuditorEnabled([out, retval] BOOL *enabled);
HRESULT setXSSAuditorEnabled([in] BOOL enabled);
+ HRESULT isFrameSetFlatteningEnabled([out, retval] BOOL *enabled);
+ HRESULT setFrameSetFlatteningEnabled([in] BOOL enabled);
+
HRESULT experimentalNotificationsEnabled([out, retval] BOOL *enabled);
HRESULT setExperimentalNotificationsEnabled([in] BOOL enabled);
diff --git a/WebKit/win/Interfaces/WebKit.idl b/WebKit/win/Interfaces/WebKit.idl
index 94dc697..3cd748c 100644
--- a/WebKit/win/Interfaces/WebKit.idl
+++ b/WebKit/win/Interfaces/WebKit.idl
@@ -294,4 +294,3 @@ library WebKit
[default] interface IWebGeolocationPosition;
}
}
-
diff --git a/WebKit/win/WebFrame.cpp b/WebKit/win/WebFrame.cpp
index c0c1601..b7ad014 100644
--- a/WebKit/win/WebFrame.cpp
+++ b/WebKit/win/WebFrame.cpp
@@ -2018,11 +2018,17 @@ void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext* spoolCt
CGContextRestoreGState(pctx);
}
#elif PLATFORM(CAIRO)
-static float scaleFactor(HDC printDC, const IntRect& pageRect)
+static float scaleFactor(HDC printDC, const IntRect& marginRect, const IntRect& pageRect)
{
const IntRect& printRect = printerRect(printDC);
- float scale = static_cast<float>(printRect.width()) / static_cast<float>(pageRect.width());
+ IntRect adjustedRect = IntRect(
+ printRect.x() + marginRect.x(),
+ printRect.y() + marginRect.y(),
+ printRect.width() - marginRect.x() - marginRect.right(),
+ printRect.height() - marginRect.y() - marginRect.bottom());
+
+ float scale = static_cast<float>(adjustedRect.width()) / static_cast<float>(pageRect.width());
if (!scale)
scale = 1.0;
@@ -2038,8 +2044,9 @@ static HDC hdcFromContext(PlatformGraphicsContext* pctx)
void WebFrame::drawHeader(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, float headerHeight)
{
HDC hdc = hdcFromContext(pctx);
+ const IntRect& marginRect = printerMarginRect(hdc);
- const float scale = scaleFactor(hdc, pageRect);
+ const float scale = scaleFactor(hdc, marginRect, pageRect);
int x = static_cast<int>(scale * pageRect.x());
int y = 0;
RECT headerRect = {x, y, x + static_cast<int>(scale * pageRect.width()), y + static_cast<int>(scale * headerHeight)};
@@ -2050,8 +2057,9 @@ void WebFrame::drawHeader(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, con
void WebFrame::drawFooter(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, UINT page, UINT pageCount, float headerHeight, float footerHeight)
{
HDC hdc = hdcFromContext(pctx);
+ const IntRect& marginRect = printerMarginRect(hdc);
- const float scale = scaleFactor(hdc, pageRect);
+ const float scale = scaleFactor(hdc, marginRect, pageRect);
int x = static_cast<int>(scale * pageRect.x());
int y = static_cast<int>(scale * max(static_cast<int>(headerHeight) + pageRect.height(), m_pageHeight-static_cast<int>(footerHeight)));
RECT footerRect = {x, y, x + static_cast<int>(scale * pageRect.width()), y + static_cast<int>(scale * footerHeight)};
@@ -2064,24 +2072,34 @@ void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext* spoolCt
Frame* coreFrame = core(this);
const IntRect& pageRect = m_pageRects[page];
- IntRect marginRect = printerMarginRect(printDC);
+ const IntRect& marginRect = printerMarginRect(printDC);
cairo_save(pctx);
- float scale = scaleFactor(printDC, pageRect);
+ spoolCtx->save();
+ float scale = scaleFactor(printDC, marginRect, pageRect);
cairo_scale(pctx, scale, scale);
- cairo_translate(pctx, -pageRect.x() + marginRect.x(), -pageRect.y() + marginRect.y() + headerHeight);
+ IntRect cairoMarginRect (marginRect);
+ cairoMarginRect.scale (1 / scale);
+
+ // Modify Cairo and GDI World Transform to account for margin in the
+ // subsequent WebKit-controlled 'paintContents' drawing operations:
+ spoolCtx->translate(cairoMarginRect.x(), cairoMarginRect.y() + headerHeight);
+
+ // Modify Cairo (only) to account for page position.
+ cairo_translate(pctx, -pageRect.x(), -pageRect.y());
coreFrame->view()->paintContents(spoolCtx, pageRect);
- cairo_translate(pctx, pageRect.x() - marginRect.x(), pageRect.y() - marginRect.y() - headerHeight);
+ cairo_translate(pctx, pageRect.x(), pageRect.y());
XFORM originalWorld;
::GetWorldTransform(printDC, &originalWorld);
- // Position world transform to account for margin
+ // Position GDI world transform to account for margin in GDI-only
+ // header/footer calls
XFORM newWorld = originalWorld;
- newWorld.eDx = scale * marginRect.x();
- newWorld.eDy = scale * marginRect.y();
+ newWorld.eDx = marginRect.x();
+ newWorld.eDy = marginRect.y();
::SetWorldTransform(printDC, &newWorld);
@@ -2095,6 +2113,7 @@ void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext* spoolCt
cairo_show_page(pctx);
ASSERT(!cairo_status(pctx));
+ spoolCtx->restore();
cairo_restore(pctx);
}
#endif
diff --git a/WebKit/win/WebPreferenceKeysPrivate.h b/WebKit/win/WebPreferenceKeysPrivate.h
index 3b4197c..9f768f2 100644
--- a/WebKit/win/WebPreferenceKeysPrivate.h
+++ b/WebKit/win/WebPreferenceKeysPrivate.h
@@ -130,6 +130,8 @@
#define WebKitPluginAllowedRunTimePreferenceKey "WebKitPluginAllowedRunTime"
+#define WebKitFrameSetFlatteningEnabledPreferenceKey "WebKitFrameSetFlatteningEnabled"
+
#define WebKitAcceleratedCompositingEnabledPreferenceKey "WebKitAcceleratedCompositingEnabled"
#define WebKitCustomDragCursorsEnabledPreferenceKey "WebKitCustomDragCursorsEnabled"
diff --git a/WebKit/win/WebPreferences.cpp b/WebKit/win/WebPreferences.cpp
index c23f236..13c2ac4 100644
--- a/WebKit/win/WebPreferences.cpp
+++ b/WebKit/win/WebPreferences.cpp
@@ -43,7 +43,6 @@
#include <CoreFoundation/CoreFoundation.h>
#include <limits>
#include <shlobj.h>
-#include <shfolder.h>
#include <tchar.h>
#include <wtf/HashMap.h>
#include <wtf/OwnArrayPtr.h>
@@ -207,6 +206,7 @@ void WebPreferences::initializeDefaultSettings()
CFDictionaryAddValue(defaults, CFSTR(WebKitWebSecurityEnabledPreferenceKey), kCFBooleanTrue);
CFDictionaryAddValue(defaults, CFSTR(WebKitAllowUniversalAccessFromFileURLsPreferenceKey), kCFBooleanFalse);
CFDictionaryAddValue(defaults, CFSTR(WebKitXSSAuditorEnabledPreferenceKey), kCFBooleanTrue);
+ CFDictionaryAddValue(defaults, CFSTR(WebKitFrameSetFlatteningEnabledPreferenceKey), kCFBooleanFalse);
CFDictionaryAddValue(defaults, CFSTR(WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey), kCFBooleanTrue);
CFDictionaryAddValue(defaults, CFSTR(WebKitPluginsEnabledPreferenceKey), kCFBooleanTrue);
CFDictionaryAddValue(defaults, CFSTR(WebKitDatabasesEnabledPreferenceKey), kCFBooleanTrue);
@@ -806,6 +806,20 @@ HRESULT STDMETHODCALLTYPE WebPreferences::setXSSAuditorEnabled(
return S_OK;
}
+HRESULT STDMETHODCALLTYPE WebPreferences::isFrameSetFlatteningEnabled(
+ /* [retval][out] */ BOOL* enabled)
+{
+ *enabled = boolValueForKey(CFSTR(WebKitFrameSetFlatteningEnabledPreferenceKey));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE WebPreferences::setFrameSetFlatteningEnabled(
+ /* [in] */ BOOL enabled)
+{
+ setBoolValue(CFSTR(WebKitFrameSetFlatteningEnabledPreferenceKey), enabled);
+ return S_OK;
+}
+
HRESULT STDMETHODCALLTYPE WebPreferences::javaScriptCanOpenWindowsAutomatically(
/* [retval][out] */ BOOL* enabled)
{
diff --git a/WebKit/win/WebPreferences.h b/WebKit/win/WebPreferences.h
index 1631e78..9209b7d 100644
--- a/WebKit/win/WebPreferences.h
+++ b/WebKit/win/WebPreferences.h
@@ -380,6 +380,12 @@ public:
virtual HRESULT STDMETHODCALLTYPE pluginAllowedRunTime(
/* [retval][out] */ UINT* allowedRunTime);
+ virtual HRESULT STDMETHODCALLTYPE isFrameSetFlatteningEnabled(
+ /* [retval][out] */ BOOL* enabled);
+
+ virtual HRESULT STDMETHODCALLTYPE setFrameSetFlatteningEnabled(
+ /* [in] */ BOOL enabled);
+
virtual HRESULT STDMETHODCALLTYPE setPreferenceForTest(
/* [in] */ BSTR key,
/* [in] */ BSTR value);
diff --git a/WebKit/win/WebView.cpp b/WebKit/win/WebView.cpp
index 6144532..880c75f 100644
--- a/WebKit/win/WebView.cpp
+++ b/WebKit/win/WebView.cpp
@@ -4645,6 +4645,11 @@ HRESULT WebView::notifyPreferencesChanged(IWebNotification* notification)
return hr;
settings->setPluginAllowedRunTime(runTime);
+ hr = prefsPrivate->isFrameSetFlatteningEnabled(&enabled);
+ if (FAILED(hr))
+ return hr;
+ settings->setFrameSetFlatteningEnabled(enabled);
+
#if USE(ACCELERATED_COMPOSITING)
hr = prefsPrivate->acceleratedCompositingEnabled(&enabled);
if (FAILED(hr))
@@ -4653,7 +4658,7 @@ HRESULT WebView::notifyPreferencesChanged(IWebNotification* notification)
#endif
#if ENABLE(3D_CANVAS)
- settings->setExperimentalWebGLEnabled(true);
+ settings->setWebGLEnabled(true);
#endif // ENABLE(3D_CANVAS)
if (!m_closeWindowTimer.isActive())
@@ -5060,7 +5065,7 @@ HRESULT STDMETHODCALLTYPE WebView::shouldClose(
}
*result = TRUE;
- if (Frame* frame = m_page->focusController()->focusedOrMainFrame())
+ if (Frame* frame = m_page->mainFrame())
*result = frame->shouldClose() ? TRUE : FALSE;
return S_OK;
}
diff --git a/WebKit/wx/ChangeLog b/WebKit/wx/ChangeLog
index 26d14d6..05efbd2 100644
--- a/WebKit/wx/ChangeLog
+++ b/WebKit/wx/ChangeLog
@@ -1,3 +1,20 @@
+2010-02-04 Kevin Ollivier <kevino@theolliviers.com>
+
+ Build fix after changes in r54345.
+
+ * WebView.cpp:
+ (wxWebView::OnKeyEvents):
+
+2010-02-04 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ REGRESSION (r53718): When scrolling a tall window by page, the overlap between pages is too big
+ https://bugs.webkit.org/show_bug.cgi?id=34371
+
+ * WebView.cpp:
+ (wxWebView::OnKeyEvents): Use Scrollbar method instead of constant.
+
2010-02-03 Kevin Watters <kevinwatters@gmail.com>
Reviewed by Kevin Ollivier.
diff --git a/WebKit/wx/WebView.cpp b/WebKit/wx/WebView.cpp
index 5fdae83..c448bbf 100644
--- a/WebKit/wx/WebView.cpp
+++ b/WebKit/wx/WebView.cpp
@@ -797,19 +797,19 @@ void wxWebView::OnKeyEvents(wxKeyEvent& event)
break;
case WXK_LEFT:
case WXK_NUMPAD_LEFT:
- frame->view()->scrollBy(WebCore::IntSize(-WebCore::cScrollbarPixelsPerLineStep, 0));
+ frame->view()->scrollBy(WebCore::IntSize(-WebCore::Scrollbar::pixelsPerLineStep(), 0));
return;
case WXK_UP:
case WXK_NUMPAD_UP:
- frame->view()->scrollBy(WebCore::IntSize(0, -WebCore::cScrollbarPixelsPerLineStep));
+ frame->view()->scrollBy(WebCore::IntSize(0, -WebCore::Scrollbar::pixelsPerLineStep()));
return;
case WXK_RIGHT:
case WXK_NUMPAD_RIGHT:
- frame->view()->scrollBy(WebCore::IntSize(WebCore::cScrollbarPixelsPerLineStep, 0));
+ frame->view()->scrollBy(WebCore::IntSize(WebCore::Scrollbar::pixelsPerLineStep(), 0));
return;
case WXK_DOWN:
case WXK_NUMPAD_DOWN:
- frame->view()->scrollBy(WebCore::IntSize(0, WebCore::cScrollbarPixelsPerLineStep));
+ frame->view()->scrollBy(WebCore::IntSize(0, WebCore::Scrollbar::pixelsPerLineStep()));
return;
case WXK_END:
case WXK_NUMPAD_END:
@@ -821,11 +821,11 @@ void wxWebView::OnKeyEvents(wxKeyEvent& event)
return;
case WXK_PAGEUP:
case WXK_NUMPAD_PAGEUP:
- frame->view()->scrollBy(WebCore::IntSize(0, -frame->view()->visibleHeight() * WebCore::cFractionToStepWhenPaging));
+ frame->view()->scrollBy(WebCore::IntSize(0, -frame->view()->visibleHeight() * WebCore::Scrollbar::minFractionToStepWhenPaging()));
return;
case WXK_PAGEDOWN:
case WXK_NUMPAD_PAGEDOWN:
- frame->view()->scrollBy(WebCore::IntSize(0, frame->view()->visibleHeight() * WebCore::cFractionToStepWhenPaging));
+ frame->view()->scrollBy(WebCore::IntSize(0, frame->view()->visibleHeight() * WebCore::Scrollbar::minFractionToStepWhenPaging()));
return;
//These we don't want turning into char events, stuff 'em
case WXK_ESCAPE: