diff options
Diffstat (limited to 'WebKit')
60 files changed, 4140 insertions, 110 deletions
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog index 6a8e76a..58c37a8 100644 --- a/WebKit/chromium/ChangeLog +++ b/WebKit/chromium/ChangeLog @@ -1,3 +1,322 @@ +2010-02-04 Yury Semikhatsky <yurys@chromium.org> + + Unreviewed. Revert 54333 which broke Chromium build. + + * WebKit.gyp: + * tests/TransparencyWinTest.cpp: Removed. + * tests/UniscribeHelperTest.cpp: Removed. + +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 + + * 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): + (WebCore::TEST_F): + +2010-02-04 Jeremy Moskovich <jeremy@chromium.org> + + Reviewed by David Levin. + + [Chromium] WebKit side of "Writing direction" context menu on OS X. + https://bugs.webkit.org/show_bug.cgi?id=34524 + + * public/WebContextMenuData.h: + (WebKit::WebContextMenuData::): + * src/ContextMenuClientImpl.cpp: + (WebKit::ContextMenuClientImpl::getCustomMenuFromDefaultItems): + +2010-02-03 Drew Wilson <atwilson@chromium.org> + + Reviewed by Alexey Proskuryakov. + + SharedWorkerScriptLoader should not be an ActiveDOMObject + https://bugs.webkit.org/show_bug.cgi?id=34513 + + * src/SharedWorkerRepository.cpp: + (WebCore::SharedWorkerScriptLoader::SharedWorkerScriptLoader): + Changed SharedWorkerScriptLoader to manage its own lifecycle without using ActiveDOMObject. + (WebCore::SharedWorkerScriptLoader::parentContext): + (WebCore::pendingLoaders): + Now we manually track pending loads so we can shut them down when the parent context shuts down. + (WebCore::SharedWorkerScriptLoader::contextDetached): + Shuts down/frees any pending worker loads. + (WebCore::SharedWorkerScriptLoader::~SharedWorkerScriptLoader): + Marks the SharedWorker object as not having pending activity if there was a load active (handles case where load was pending when parent document exits). + (WebCore::SharedWorkerScriptLoader::load): + (WebCore::SharedWorkerRepository::documentDetached): + Now calls SharedWorkerScriptLoader::contextDetached() to shutdown any pending worker loads. + +2010-02-03 Alexander Pavlov <apavlov@chromium.org> + + Reviewed by Timothy Hatcher. + + [Chromium] Return a consistent set of platforms from WebDevToolsFrontendImpl + https://bugs.webkit.org/show_bug.cgi?id=34523 + + * src/WebDevToolsFrontendImpl.cpp: + (WebKit::WebDevToolsFrontendImpl::jsPlatform): + +2010-02-02 Joel Stanley <joel@jms.id.au> + + Reviewed by David Levin. + + [Chromium] Add API method for setting caret blink frequency. + https://bugs.webkit.org/show_bug.cgi?id=31704 + + This enables the RenderThemeChromiumLinux::setCaretBlinkInterval method + to be called Chromium's API. The API is linux-only as it is currently + the only port to implement RenderTheme::setCaretBlinkInterval. + + * WebKit.gyp: Add WebRenderTheme.{h,cpp} + * public/linux/WebRenderTheme.h: Added. + * src/linux/WebRenderTheme.cpp: Added. + (WebKit::setCaretBlinkInterval): Exposed API + +2010-02-02 Shinichiro Hamaji <hamaji@chromium.org> + + Reviewed by Dimitri Glazkov. + + [Chromium] Implement WebFrameImpl::pageNumberForElementById + https://bugs.webkit.org/show_bug.cgi?id=34471 + + * public/WebFrame.h: + * src/WebFrameImpl.cpp: + (WebKit::WebFrameImpl::pageNumberForElementById): + * src/WebFrameImpl.h: + +2010-02-02 Yury Semikhatsky <yurys@chromium.org> + + Reviewed by Pavel Feldman. + + Upstream DevTools code. + + https://bugs.webkit.org/show_bug.cgi?id=34326 + + * WebKit.gyp: + * src/APUAgentDelegate.h: Added. + * src/BoundObject.cpp: Added. + (WebKit::BoundObject::BoundObject): + (WebKit::BoundObject::~BoundObject): + (WebKit::BoundObject::addProtoFunction): + (WebKit::BoundObject::build): + * src/BoundObject.h: Added. + * src/DebuggerAgent.h: Added. + * src/DebuggerAgentImpl.cpp: Added. + (WebKit::DebuggerAgentImpl::DebuggerAgentImpl): + (WebKit::DebuggerAgentImpl::~DebuggerAgentImpl): + (WebKit::DebuggerAgentImpl::getContextId): + (WebKit::DebuggerAgentImpl::debuggerOutput): + (WebKit::DebuggerAgentImpl::createUtilityContext): + (WebKit::DebuggerAgentImpl::executeUtilityFunction): + (WebKit::DebuggerAgentImpl::executeVoidJavaScript): + (WebKit::DebuggerAgentImpl::page): + * src/DebuggerAgentImpl.h: Added. + (WebKit::DebuggerAgentImpl::setAutoContinueOnException): + (WebKit::DebuggerAgentImpl::autoContinueOnException): + (WebKit::DebuggerAgentImpl::webdevtoolsAgent): + (WebKit::DebuggerAgentImpl::webView): + * src/DebuggerAgentManager.cpp: Added. + (WebKit::DebuggerAgentManager::debugHostDispatchHandler): + (WebKit::DebuggerAgentManager::debugAttach): + (WebKit::DebuggerAgentManager::debugDetach): + (WebKit::DebuggerAgentManager::onV8DebugMessage): + (WebKit::DebuggerAgentManager::pauseScript): + (WebKit::DebuggerAgentManager::executeDebuggerCommand): + (WebKit::DebuggerAgentManager::setMessageLoopDispatchHandler): + (WebKit::DebuggerAgentManager::setHostId): + (WebKit::DebuggerAgentManager::onWebViewClosed): + (WebKit::DebuggerAgentManager::onNavigate): + (WebKit::DebuggerAgentManager::sendCommandToV8): + (WebKit::DebuggerAgentManager::sendContinueCommandToV8): + (WebKit::DebuggerAgentManager::findAgentForCurrentV8Context): + (WebKit::DebuggerAgentManager::debuggerAgentForHostId): + * src/DebuggerAgentManager.h: Added. + (WebKit::DebuggerAgentManager::UtilityContextScope::UtilityContextScope): + (WebKit::DebuggerAgentManager::UtilityContextScope::~UtilityContextScope): + * src/DevToolsRPC.h: Added. + (WebKit::): + (WebKit::DevToolsRPC::Delegate::Delegate): + (WebKit::DevToolsRPC::Delegate::~Delegate): + (WebKit::DevToolsRPC::DevToolsRPC): + (WebKit::DevToolsRPC::~DevToolsRPC): + (WebKit::DevToolsRPC::sendRpcMessage): + * src/DevToolsRPCJS.h: Added. + * src/ProfilerAgent.h: Added. + * src/ProfilerAgentImpl.cpp: Added. + (WebKit::ProfilerAgentImpl::getActiveProfilerModules): + (WebKit::ProfilerAgentImpl::getLogLines): + * src/ProfilerAgentImpl.h: Added. + (WebKit::ProfilerAgentImpl::ProfilerAgentImpl): + (WebKit::ProfilerAgentImpl::~ProfilerAgentImpl): + * src/ToolsAgent.h: Added. + * src/WebDevToolsAgentImpl.cpp: Added. + (WebKit::): + (WebKit::WebDevToolsAgentImpl::WebDevToolsAgentImpl): + (WebKit::WebDevToolsAgentImpl::~WebDevToolsAgentImpl): + (WebKit::WebDevToolsAgentImpl::disposeUtilityContext): + (WebKit::WebDevToolsAgentImpl::unhideResourcesPanelIfNecessary): + (WebKit::WebDevToolsAgentImpl::attach): + (WebKit::WebDevToolsAgentImpl::detach): + (WebKit::WebDevToolsAgentImpl::didNavigate): + (WebKit::WebDevToolsAgentImpl::didCommitProvisionalLoad): + (WebKit::WebDevToolsAgentImpl::didClearWindowObject): + (WebKit::WebDevToolsAgentImpl::forceRepaint): + (WebKit::WebDevToolsAgentImpl::dispatchOnInspectorController): + (WebKit::WebDevToolsAgentImpl::dispatchOnInjectedScript): + (WebKit::WebDevToolsAgentImpl::executeVoidJavaScript): + (WebKit::WebDevToolsAgentImpl::dispatchMessageFromFrontend): + (WebKit::WebDevToolsAgentImpl::inspectElementAt): + (WebKit::WebDevToolsAgentImpl::setRuntimeFeatureEnabled): + (WebKit::WebDevToolsAgentImpl::sendRpcMessage): + (WebKit::WebDevToolsAgentImpl::compileUtilityScripts): + (WebKit::WebDevToolsAgentImpl::initDevToolsAgentHost): + (WebKit::WebDevToolsAgentImpl::createInspectorBackendV8Wrapper): + (WebKit::WebDevToolsAgentImpl::resetInspectorFrontendProxy): + (WebKit::WebDevToolsAgentImpl::setApuAgentEnabled): + (WebKit::WebDevToolsAgentImpl::jsDispatchOnClient): + (WebKit::WebDevToolsAgentImpl::jsDispatchToApu): + (WebKit::WebDevToolsAgentImpl::jsEvaluateOnSelf): + (WebKit::WebDevToolsAgentImpl::jsOnRuntimeFeatureStateChanged): + (WebKit::WebDevToolsAgentImpl::inspectorController): + (WebKit::WebDevToolsAgentImpl::identifierForInitialRequest): + (WebKit::WebDevToolsAgentImpl::willSendRequest): + (WebKit::WebDevToolsAgentImpl::didReceiveData): + (WebKit::WebDevToolsAgentImpl::didReceiveResponse): + (WebKit::WebDevToolsAgentImpl::didFinishLoading): + (WebKit::WebDevToolsAgentImpl::didFailLoading): + (WebKit::WebDevToolsAgentImpl::evaluateInWebInspector): + (WebKit::WebDevToolsAgentImpl::setTimelineProfilingEnabled): + (WebKit::WebDevToolsAgent::create): + (WebKit::WebDevToolsAgent::executeDebuggerCommand): + (WebKit::WebDevToolsAgent::debuggerPauseScript): + (WebKit::WebDevToolsAgent::setMessageLoopDispatchHandler): + (WebKit::WebDevToolsAgent::dispatchMessageFromFrontendOnIOThread): + * src/WebDevToolsAgentImpl.h: Added. + (WebKit::WebDevToolsAgentImpl::hostId): + * src/WebDevToolsFrontendImpl.cpp: Added. + (WebKit::ToV8String): + (WebKit::WebDevToolsFrontend::create): + (WebKit::WebDevToolsFrontendImpl::WebDevToolsFrontendImpl): + (WebKit::WebDevToolsFrontendImpl::~WebDevToolsFrontendImpl): + (WebKit::WebDevToolsFrontendImpl::dispatchMessageFromAgent): + (WebKit::WebDevToolsFrontendImpl::executeScript): + (WebKit::WebDevToolsFrontendImpl::dispatchOnWebInspector): + (WebKit::WebDevToolsFrontendImpl::sendRpcMessage): + (WebKit::WebDevToolsFrontendImpl::contextMenuItemSelected): + (WebKit::WebDevToolsFrontendImpl::contextMenuCleared): + (WebKit::WebDevToolsFrontendImpl::jsLoaded): + (WebKit::WebDevToolsFrontendImpl::jsPlatform): + (WebKit::WebDevToolsFrontendImpl::jsPort): + (WebKit::WebDevToolsFrontendImpl::jsCopyText): + (WebKit::WebDevToolsFrontendImpl::jsActivateWindow): + (WebKit::WebDevToolsFrontendImpl::jsCloseWindow): + (WebKit::WebDevToolsFrontendImpl::jsDockWindow): + (WebKit::WebDevToolsFrontendImpl::jsUndockWindow): + (WebKit::WebDevToolsFrontendImpl::jsLocalizedStringsURL): + (WebKit::WebDevToolsFrontendImpl::jsHiddenPanels): + (WebKit::WebDevToolsFrontendImpl::jsDebuggerCommand): + (WebKit::WebDevToolsFrontendImpl::jsSetting): + (WebKit::WebDevToolsFrontendImpl::jsSetSetting): + (WebKit::WebDevToolsFrontendImpl::jsDebuggerPauseScript): + (WebKit::WebDevToolsFrontendImpl::jsWindowUnloading): + (WebKit::WebDevToolsFrontendImpl::jsShowContextMenu): + * src/WebDevToolsFrontendImpl.h: Added. + (WebKit::WebDevToolsFrontendImpl::MenuProvider::create): + (WebKit::WebDevToolsFrontendImpl::MenuProvider::~MenuProvider): + (WebKit::WebDevToolsFrontendImpl::MenuProvider::disconnect): + (WebKit::WebDevToolsFrontendImpl::MenuProvider::populateContextMenu): + (WebKit::WebDevToolsFrontendImpl::MenuProvider::contextMenuItemSelected): + (WebKit::WebDevToolsFrontendImpl::MenuProvider::contextMenuCleared): + (WebKit::WebDevToolsFrontendImpl::MenuProvider::MenuProvider): + +2010-02-01 Jeremy Orlow <jorlow@chromium.org> + + Reviewed by Darin Fisher. + + [Chromium] Add WebSecurityOrigin::createFromString factory + https://bugs.webkit.org/show_bug.cgi?id=34460 + + * public/WebSecurityOrigin.h: + * src/WebSecurityOrigin.cpp: + (WebKit::WebSecurityOrigin::createFromString): + +2010-02-02 Kent Tamura <tkent@chromium.org> + + Reviewed by Darin Fisher. + + [Chromium] Should not select a word on right-click. + https://bugs.webkit.org/show_bug.cgi?id=33364 + + For non-Mac platforms, do not select a word around the caret when + a context menu is opening. This behavior is not common in non-Mac + platforms, and it prevents pasting with a context menu. + + In order that the spell checker works without the selection, we + introduce WebFrame::selectWordAroundCaret(). We can replace a word + around the caret with selectWordAroundCaret() + replaceSelection(). + + * public/WebFrame.h: Add pure selectWordAroundCaret() declaration. + * src/ContextMenuClientImpl.cpp: + (WebKit::selectMisspelledWord): Move word-selection code to + WebFrameImpl::selectWordAroundPosition(), and clear the selection + on non-Mac. + * src/WebFrameImpl.cpp: + (WebKit::WebFrameImpl::selectWordAroundPosition): + (WebKit::WebFrameImpl::selectWordAroundCaret): + * src/WebFrameImpl.h: Add selectWordAroundCaret() declaration. + +2010-02-01 Shinichiro Hamaji <hamaji@chromium.org> + + Unreviewed attempt to fix the broken build. + + This was introduced in http://trac.webkit.org/changeset/54182 + + * src/WebViewImpl.cpp: + (WebKit::WebViewImpl::performMediaPlayerAction): + +2010-01-27 Matt Perry <mpcomplete@chromium.org> + + Reviewed by Eric Seidel. + + Add support for addUserScript to chromium port. + + * public/WebView.h: + * src/WebViewImpl.cpp: + (WebKit::WebViewImpl::addUserScript): + (WebKit::WebViewImpl::removeAllUserContent): + * src/WebViewImpl.h: + +2010-01-29 Philippe Normand <pnormand@igalia.com> + + Reviewed by Eric Carlson. + + [GTK] set playbin mute property depending on volume value + https://bugs.webkit.org/show_bug.cgi?id=31586 + + New API in MediaPlayer for mute control + + * public/WebMediaPlayerClient.h: + * src/WebMediaPlayerClientImpl.cpp: + (WebKit::WebMediaPlayerClientImpl::volumeChanged): + (WebKit::WebMediaPlayerClientImpl::muteChanged): + * src/WebMediaPlayerClientImpl.h: + 2010-01-31 Kent Tamura <tkent@chromium.org> Reviewed by Jeremy Orlow. @@ -12,6 +331,17 @@ 2010-01-29 Jeremy Orlow <jorlow@chromium.org> + Reviewed by Eric Seidel. + + [Chromium] Clean up WebStorageArea + https://bugs.webkit.org/show_bug.cgi?id=34353 + + Get rid of legacy glue code and fix a typo. + + * public/WebStorageArea.h: + +2010-01-29 Jeremy Orlow <jorlow@chromium.org> + Reviewed by Dimitri Glazkov. A first step towards the Indexed Database API diff --git a/WebKit/chromium/WebKit.gyp b/WebKit/chromium/WebKit.gyp index 3b5a17f..4f6d3f6 100644 --- a/WebKit/chromium/WebKit.gyp +++ b/WebKit/chromium/WebKit.gyp @@ -70,6 +70,7 @@ 'sources': [ 'public/gtk/WebInputEventFactory.h', 'public/linux/WebFontRendering.h', + 'public/linux/WebRenderTheme.h', 'public/x11/WebScreenInfoFactory.h', 'public/mac/WebInputEventFactory.h', 'public/mac/WebScreenInfoFactory.h', @@ -192,6 +193,7 @@ 'public/win/WebSandboxSupport.h', 'public/win/WebScreenInfoFactory.h', 'public/win/WebScreenInfoFactory.h', + 'src/APUAgentDelegate.h', 'src/ApplicationCacheHost.cpp', 'src/ApplicationCacheHostInternal.h', 'src/AssertMatchingEnums.cpp', @@ -199,6 +201,8 @@ 'src/AutocompletePopupMenuClient.h', 'src/BackForwardListClientImpl.cpp', 'src/BackForwardListClientImpl.h', + 'src/BoundObject.cpp', + 'src/BoundObject.h', 'src/ChromeClientImpl.cpp', 'src/ChromeClientImpl.h', 'src/ChromiumBridge.cpp', @@ -207,6 +211,13 @@ 'src/ContextMenuClientImpl.cpp', 'src/ContextMenuClientImpl.h', 'src/DatabaseObserver.cpp', + 'src/DebuggerAgent.h', + 'src/DebuggerAgentImpl.cpp', + 'src/DebuggerAgentImpl.h', + 'src/DebuggerAgentManager.cpp', + 'src/DebuggerAgentManager.h', + 'src/DevToolsRPC.h', + 'src/DevToolsRPCJS.h', 'src/DOMUtilitiesPrivate.cpp', 'src/DOMUtilitiesPrivate.h', 'src/DragClientImpl.cpp', @@ -223,6 +234,7 @@ 'src/InspectorClientImpl.cpp', 'src/InspectorClientImpl.h', 'src/linux/WebFontRendering.cpp', + 'src/linux/WebRenderTheme.cpp', 'src/x11/WebScreenInfoFactory.cpp', 'src/mac/WebInputEventFactory.mm', 'src/mac/WebScreenInfoFactory.mm', @@ -232,6 +244,9 @@ 'src/NotificationPresenterImpl.cpp', 'src/PlatformMessagePortChannel.cpp', 'src/PlatformMessagePortChannel.h', + 'src/ProfilerAgent.h', + 'src/ProfilerAgentImpl.cpp', + 'src/ProfilerAgentImpl.h', 'src/ResourceHandle.cpp', 'src/SharedWorkerRepository.cpp', 'src/SocketStreamHandle.cpp', @@ -243,6 +258,7 @@ 'src/StorageNamespaceProxy.cpp', 'src/StorageNamespaceProxy.h', 'src/TemporaryGlue.h', + 'src/ToolsAgent.h', 'src/WebAccessibilityCache.cpp', 'src/WebAccessibilityCacheImpl.cpp', 'src/WebAccessibilityCacheImpl.h', @@ -259,6 +275,10 @@ 'src/WebDatabase.cpp', 'src/WebDataSourceImpl.cpp', 'src/WebDataSourceImpl.h', + 'src/WebDevToolsAgentImpl.cpp', + 'src/WebDevToolsAgentImpl.h', + 'src/WebDevToolsFrontendImpl.cpp', + 'src/WebDevToolsFrontendImpl.h', 'src/WebDocument.cpp', 'src/WebDragData.cpp', 'src/WebElement.cpp', diff --git a/WebKit/chromium/public/WebContextMenuData.h b/WebKit/chromium/public/WebContextMenuData.h index b4acb1c..049da9c 100644 --- a/WebKit/chromium/public/WebContextMenuData.h +++ b/WebKit/chromium/public/WebContextMenuData.h @@ -97,6 +97,18 @@ struct WebContextMenuData { // Whether context is editable. bool isEditable; + enum CheckableMenuItemFlags { + CheckableMenuItemDisabled = 0x0, + CheckableMenuItemEnabled = 0x1, + CheckableMenuItemChecked = 0x2, + }; + + // Writing direction menu items. + // Currently only used on OS X. + int writingDirectionDefault; + int writingDirectionLeftToRight; + int writingDirectionRightToLeft; + enum EditFlags { CanDoNone = 0x0, CanUndo = 0x1, diff --git a/WebKit/chromium/public/WebFrame.h b/WebKit/chromium/public/WebFrame.h index 4197c23..a56e6cb 100644 --- a/WebKit/chromium/public/WebFrame.h +++ b/WebKit/chromium/public/WebFrame.h @@ -357,6 +357,11 @@ public: virtual WebString selectionAsText() const = 0; virtual WebString selectionAsMarkup() const = 0; + // Expands the selection to a word around the caret and returns + // true. Does nothing and returns false if there is no caret or + // there is ranged selection. + virtual bool selectWordAroundCaret() = 0; + // Printing ------------------------------------------------------------ @@ -478,6 +483,13 @@ public: // used to support layout tests. virtual WebString counterValueForElementById(const WebString& id) const = 0; + + // Returns the number of page where the specified element will be put. + // This method is used to support layout tests. + virtual int pageNumberForElementById(const WebString& id, + float pageWidthInPixels, + float pageHeightInPixels) const = 0; + protected: ~WebFrame() { } }; diff --git a/WebKit/chromium/public/WebMediaPlayerClient.h b/WebKit/chromium/public/WebMediaPlayerClient.h index 558fb4a..47ce64e 100644 --- a/WebKit/chromium/public/WebMediaPlayerClient.h +++ b/WebKit/chromium/public/WebMediaPlayerClient.h @@ -40,7 +40,8 @@ class WebMediaPlayerClient { public: virtual void networkStateChanged() = 0; virtual void readyStateChanged() = 0; - virtual void volumeChanged() = 0; + virtual void volumeChanged(float) = 0; + virtual void muteChanged(bool) = 0; virtual void timeChanged() = 0; virtual void repaint() = 0; virtual void durationChanged() = 0; diff --git a/WebKit/chromium/public/WebSecurityOrigin.h b/WebKit/chromium/public/WebSecurityOrigin.h index 7b04aac..1285b10 100644 --- a/WebKit/chromium/public/WebSecurityOrigin.h +++ b/WebKit/chromium/public/WebSecurityOrigin.h @@ -55,7 +55,9 @@ public: return *this; } + // FIXME: This should return a WebSecurityOrigin, not a pointer to one. WEBKIT_API static WebSecurityOrigin* createFromDatabaseIdentifier(const WebString& databaseIdentifier); + WEBKIT_API static WebSecurityOrigin createFromString(const WebString&); WEBKIT_API void reset(); WEBKIT_API void assign(const WebSecurityOrigin&); diff --git a/WebKit/chromium/public/WebStorageArea.h b/WebKit/chromium/public/WebStorageArea.h index 302e10c..19d98c6 100644 --- a/WebKit/chromium/public/WebStorageArea.h +++ b/WebKit/chromium/public/WebStorageArea.h @@ -57,44 +57,17 @@ 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 we've + // 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. - // FIXME: The following is a hack to keep Chromium compiling until the other half is landed. Remove soon. - virtual void setItem(const WebString& key, const WebString& newValue, const WebURL& url, bool& quotaException) // Deprecated. - { - WebString oldValue; - setItem(key, newValue, url, quotaException, oldValue); - } - virtual void setItem(const WebString& key, const WebString& newValue, const WebURL& url, bool& quotaException, WebString& oldValue) - { - setItem(key, newValue, url, quotaException); - } + virtual void setItem(const WebString& key, const WebString& newValue, const WebURL& url, bool& quotaException, WebString& oldValue) = 0; // Remove the value associated with a particular key. url is the url that should be used // if a storage event fires. - // FIXME: The following is a hack to keep Chromium compiling until the other half is landed. Remove soon. - virtual void removeItem(const WebString& key, const WebURL& url) // Deprecated. - { - WebString oldValue; - removeItem(key, url, oldValue); - } - virtual void removeItem(const WebString& key, const WebURL& url, WebString& oldValue) - { - removeItem(key, url); - } + virtual void removeItem(const WebString& key, const WebURL& url, WebString& oldValue) = 0; // Clear all key/value pairs. url is the url that should be used if a storage event fires. - // FIXME: The following is a hack to keep Chromium compiling until the other half is landed. Remove soon. - virtual void clear(const WebURL& url) // Deprecated. - { - bool somethingCleared; - clear(url, somethingCleared); - } - virtual void clear(const WebURL& url, bool& somethingCleared) - { - clear(url); - } + virtual void clear(const WebURL& url, bool& somethingCleared) = 0; }; } // namespace WebKit diff --git a/WebKit/chromium/public/WebView.h b/WebKit/chromium/public/WebView.h index aba556c..7b3294f 100644 --- a/WebKit/chromium/public/WebView.h +++ b/WebKit/chromium/public/WebView.h @@ -262,6 +262,10 @@ public: unsigned inactiveBackgroundColor, unsigned inactiveForegroundColor) = 0; + // User scripts -------------------------------------------------------- + virtual void addUserScript(const WebString& sourceCode, + bool runAtStart) = 0; + virtual void removeAllUserContent() = 0; // Modal dialog support ------------------------------------------------ diff --git a/WebKit/chromium/public/linux/WebRenderTheme.h b/WebKit/chromium/public/linux/WebRenderTheme.h new file mode 100644 index 0000000..e3be69d --- /dev/null +++ b/WebKit/chromium/public/linux/WebRenderTheme.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2009 Joel Stanley. 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 WebRenderTheme_h +#define WebRenderTheme_h + +#include "../WebCommon.h" + +namespace WebKit { + +// Set caret blink interval for text input areas. +WEBKIT_API void setCaretBlinkInterval(double); + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/APUAgentDelegate.h b/WebKit/chromium/src/APUAgentDelegate.h new file mode 100644 index 0000000..70be702 --- /dev/null +++ b/WebKit/chromium/src/APUAgentDelegate.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 APUAgentDelegate_h +#define APUAgentDelegate_h + +#include "DevToolsRPC.h" + +namespace WebKit { + +#define APU_AGENT_DELEGATE_STRUCT(METHOD0, METHOD1, METHOD2, METHOD3, MEHTOD4, METHOD5) \ + /* Sends a json object to apu. */ \ + METHOD1(dispatchToApu, String /* data */) + +DEFINE_RPC_CLASS(ApuAgentDelegate, APU_AGENT_DELEGATE_STRUCT) + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/BoundObject.cpp b/WebKit/chromium/src/BoundObject.cpp new file mode 100644 index 0000000..90096c2 --- /dev/null +++ b/WebKit/chromium/src/BoundObject.cpp @@ -0,0 +1,79 @@ +/* + * 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 "BoundObject.h" + +#include "V8Proxy.h" + +namespace WebKit { + +BoundObject::BoundObject(v8::Handle<v8::Context> context, void* v8This, const char* objectName) + : m_objectName(objectName) + , m_context(context) + , m_v8This(v8This) +{ + v8::Context::Scope contextScope(context); + v8::Local<v8::FunctionTemplate> localTemplate = v8::FunctionTemplate::New(WebCore::V8Proxy::checkNewLegal); + m_hostTemplate = v8::Persistent<v8::FunctionTemplate>::New(localTemplate); + m_hostTemplate->SetClassName(v8::String::New(objectName)); +} + +BoundObject::~BoundObject() +{ + m_hostTemplate.Dispose(); +} + +void BoundObject::addProtoFunction(const char* name, v8::InvocationCallback callback) +{ + v8::Context::Scope contextScope(m_context); + v8::Local<v8::Signature> signature = v8::Signature::New(m_hostTemplate); + v8::Local<v8::ObjectTemplate> proto = m_hostTemplate->PrototypeTemplate(); + v8::Local<v8::External> v8This = v8::External::New(m_v8This); + proto->Set( + v8::String::New(name), + v8::FunctionTemplate::New( + callback, + v8This, + signature), + static_cast<v8::PropertyAttribute>(v8::DontDelete)); +} + +void BoundObject::build() +{ + v8::Context::Scope contextScope(m_context); + v8::Local<v8::Function> constructor = m_hostTemplate->GetFunction(); + v8::Local<v8::Object> boundObject = WebCore::SafeAllocation::newInstance(constructor); + + v8::Handle<v8::Object> global = m_context->Global(); + global->Set(v8::String::New(m_objectName), boundObject); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/BoundObject.h b/WebKit/chromium/src/BoundObject.h new file mode 100644 index 0000000..769e83f --- /dev/null +++ b/WebKit/chromium/src/BoundObject.h @@ -0,0 +1,60 @@ +/* + * 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 BoundObject_h +#define BoundObject_h + +#include <v8.h> +#include <wtf/Noncopyable.h> + +namespace WebKit { + +// BoundObject is a helper class that lets you map JavaScript method calls +// directly to C++ method calls. It should be destroyed once JS object is +// built. +class BoundObject : public Noncopyable { +public: + BoundObject(v8::Handle<v8::Context> context, void* v8This, const char* objectName); + virtual ~BoundObject(); + + void addProtoFunction(const char* name, v8::InvocationCallback callback); + void build(); + +private: + v8::HandleScope m_handleScope; + const char* m_objectName; + v8::Handle<v8::Context> m_context; + v8::Persistent<v8::FunctionTemplate> m_hostTemplate; + void* m_v8This; +}; + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/ContextMenuClientImpl.cpp b/WebKit/chromium/src/ContextMenuClientImpl.cpp index 72b861f..8472082 100644 --- a/WebKit/chromium/src/ContextMenuClientImpl.cpp +++ b/WebKit/chromium/src/ContextMenuClientImpl.cpp @@ -31,6 +31,8 @@ #include "config.h" #include "ContextMenuClientImpl.h" +#include "CSSPropertyNames.h" +#include "CSSStyleDeclaration.h" #include "ContextMenu.h" #include "Document.h" #include "DocumentLoader.h" @@ -89,7 +91,7 @@ static bool isASingleWord(const String& text) // Helper function to get misspelled word on which context menu // is to be evolked. This function also sets the word on which context menu // has been evoked to be the selected word, as required. This function changes -// the selection only when there were no selected characters. +// the selection only when there were no selected characters on OS X. static String selectMisspelledWord(const ContextMenu* defaultMenu, Frame* selectedFrame) { // First select from selectedText to check for multiple word selection. @@ -110,27 +112,21 @@ static String selectMisspelledWord(const ContextMenu* defaultMenu, Frame* select VisiblePosition pos(innerNode->renderer()->positionForPoint( hitTestResult.localPoint())); - VisibleSelection selection; - if (pos.isNotNull()) { - selection = VisibleSelection(pos); - selection.expandUsingGranularity(WordGranularity); - } - - if (selection.isRange()) - selectedFrame->setSelectionGranularity(WordGranularity); - - if (selectedFrame->shouldChangeSelection(selection)) - selectedFrame->selection()->setSelection(selection); + if (pos.isNull()) + return misspelledWord; // It is empty. + WebFrameImpl::selectWordAroundPosition(selectedFrame, pos); misspelledWord = selectedFrame->selectedText().stripWhiteSpace(); +#if OS(DARWIN) // If misspelled word is still empty, then that portion should not be // selected. Set the selection to that position only, and do not expand. - if (misspelledWord.isEmpty()) { - selection = VisibleSelection(pos); - selectedFrame->selection()->setSelection(selection); - } - + if (misspelledWord.isEmpty()) + selectedFrame->selection()->setSelection(VisibleSelection(pos)); +#else + // On non-Mac, right-click should not make a range selection in any case. + selectedFrame->selection()->setSelection(VisibleSelection(pos)); +#endif return misspelledWord; } @@ -207,6 +203,22 @@ PlatformMenuDescription ContextMenuClientImpl::getCustomMenuFromDefaultItems( } } +#if OS(DARWIN) + // Writing direction context menu. + data.writingDirectionDefault = WebContextMenuData::CheckableMenuItemDisabled; + data.writingDirectionLeftToRight = WebContextMenuData::CheckableMenuItemEnabled; + data.writingDirectionRightToLeft = WebContextMenuData::CheckableMenuItemEnabled; + + ExceptionCode ec = 0; + RefPtr<CSSStyleDeclaration> style = selectedFrame->document()->createCSSStyleDeclaration(); + style->setProperty(CSSPropertyDirection, "ltr", false, ec); + if (selectedFrame->editor()->selectionHasStyle(style.get()) != FalseTriState) + data.writingDirectionLeftToRight |= WebContextMenuData::CheckableMenuItemChecked; + style->setProperty(CSSPropertyDirection, "rtl", false, ec); + if (selectedFrame->editor()->selectionHasStyle(style.get()) != FalseTriState) + data.writingDirectionRightToLeft |= WebContextMenuData::CheckableMenuItemChecked; +#endif // OS(DARWIN) + // Now retrieve the security info. DocumentLoader* dl = selectedFrame->loader()->documentLoader(); WebDataSource* ds = WebDataSourceImpl::fromDocumentLoader(dl); diff --git a/WebKit/chromium/src/DebuggerAgent.h b/WebKit/chromium/src/DebuggerAgent.h new file mode 100644 index 0000000..cac9686 --- /dev/null +++ b/WebKit/chromium/src/DebuggerAgent.h @@ -0,0 +1,54 @@ +/* + * 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 DebuggerAgent_h +#define DebuggerAgent_h + +#include "DevToolsRPC.h" + +namespace WebKit { + +#define DEBUGGER_AGENT_STRUCT(METHOD0, METHOD1, METHOD2, METHOD3, METHOD4, METHOD5) \ + /* Requests global context id of the inspected tab. */ \ + METHOD0(getContextId) + +DEFINE_RPC_CLASS(DebuggerAgent, DEBUGGER_AGENT_STRUCT) + +#define DEBUGGER_AGENT_DELEGATE_STRUCT(METHOD0, METHOD1, METHOD2, METHOD3, METHOD4, METHOD5) \ + METHOD1(debuggerOutput, String /* output text */) \ + \ + /* Pushes debugger context id into the client. */ \ + METHOD1(setContextId, int /* context id */) + +DEFINE_RPC_CLASS(DebuggerAgentDelegate, DEBUGGER_AGENT_DELEGATE_STRUCT) + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/DebuggerAgentImpl.cpp b/WebKit/chromium/src/DebuggerAgentImpl.cpp new file mode 100644 index 0000000..0c3d1ea --- /dev/null +++ b/WebKit/chromium/src/DebuggerAgentImpl.cpp @@ -0,0 +1,204 @@ +/* + * 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 "DebuggerAgentImpl.h" + +#include "DebuggerAgentManager.h" +#include "Document.h" +#include "Frame.h" +#include "Page.h" +#include "V8Binding.h" +#include "V8DOMWindow.h" +#include "V8Index.h" +#include "V8Proxy.h" +#include "WebDevToolsAgentImpl.h" +#include "WebViewImpl.h" +#include <wtf/HashSet.h> +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +using WebCore::DOMWindow; +using WebCore::Document; +using WebCore::Frame; +using WebCore::Page; +using WebCore::String; +using WebCore::V8ClassIndex; +using WebCore::V8Custom; +using WebCore::V8DOMWindow; +using WebCore::V8DOMWrapper; +using WebCore::V8Proxy; + +namespace WebKit { + +DebuggerAgentImpl::DebuggerAgentImpl( + WebViewImpl* webViewImpl, + DebuggerAgentDelegate* delegate, + WebDevToolsAgentImpl* webdevtoolsAgent) + : m_webViewImpl(webViewImpl) + , m_delegate(delegate) + , m_webdevtoolsAgent(webdevtoolsAgent) + , m_autoContinueOnException(false) +{ + DebuggerAgentManager::debugAttach(this); +} + +DebuggerAgentImpl::~DebuggerAgentImpl() +{ + DebuggerAgentManager::debugDetach(this); +} + +void DebuggerAgentImpl::getContextId() +{ + m_delegate->setContextId(m_webdevtoolsAgent->hostId()); +} + +void DebuggerAgentImpl::debuggerOutput(const String& command) +{ + m_delegate->debuggerOutput(command); + m_webdevtoolsAgent->forceRepaint(); +} + +// static +void DebuggerAgentImpl::createUtilityContext(Frame* frame, v8::Persistent<v8::Context>* context) +{ + v8::HandleScope scope; + + // 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::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New(); + + // TODO(yurys): provide a function in v8 bindings that would make the + // utility context more like main world context of the inspected frame, + // otherwise we need to manually make it satisfy various invariants + // that V8Proxy::getEntered and some other V8Proxy methods expect to find + // on v8 contexts on the contexts stack. + // See V8Proxy::createNewContext. + // + // Install a security handler with V8. + globalTemplate->SetAccessCheckCallbacks( + V8DOMWindow::namedSecurityCheck, + V8DOMWindow::indexedSecurityCheck, + v8::Integer::New(V8ClassIndex::DOMWINDOW)); + // We set number of internal fields to match that in V8DOMWindow wrapper. + // See http://crbug.com/28961 + globalTemplate->SetInternalFieldCount(V8DOMWindow::internalFieldCount); + + *context = v8::Context::New(0 /* no extensions */, globalTemplate, v8::Handle<v8::Object>()); + v8::Context::Scope contextScope(*context); + v8::Handle<v8::Object> global = (*context)->Global(); + + v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__"); + 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); +} + +String DebuggerAgentImpl::executeUtilityFunction( + v8::Handle<v8::Context> context, + int callId, + const char* object, + const String &functionName, + const String& jsonArgs, + bool async, + String* exception) +{ + v8::HandleScope scope; + ASSERT(!context.IsEmpty()); + if (context.IsEmpty()) { + *exception = "No window context."; + return ""; + } + v8::Context::Scope contextScope(context); + + DebuggerAgentManager::UtilityContextScope utilityScope; + + v8::Handle<v8::Object> dispatchObject = v8::Handle<v8::Object>::Cast( + context->Global()->Get(v8::String::New(object))); + + v8::Handle<v8::Value> dispatchFunction = dispatchObject->Get(v8::String::New("dispatch")); + ASSERT(dispatchFunction->IsFunction()); + v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(dispatchFunction); + + v8::Handle<v8::String> functionNameWrapper = v8::Handle<v8::String>( + v8::String::New(functionName.utf8().data())); + v8::Handle<v8::String> jsonArgsWrapper = v8::Handle<v8::String>( + v8::String::New(jsonArgs.utf8().data())); + v8::Handle<v8::Number> callIdWrapper = v8::Handle<v8::Number>( + v8::Number::New(async ? callId : 0)); + + v8::Handle<v8::Value> args[] = { + functionNameWrapper, + jsonArgsWrapper, + callIdWrapper + }; + + v8::TryCatch tryCatch; + v8::Handle<v8::Value> resObj = function->Call(context->Global(), 3, args); + if (tryCatch.HasCaught()) { + v8::Local<v8::Message> message = tryCatch.Message(); + if (message.IsEmpty()) + *exception = "Unknown exception"; + else + *exception = WebCore::toWebCoreString(message->Get()); + return ""; + } + 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(); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/DebuggerAgentImpl.h b/WebKit/chromium/src/DebuggerAgentImpl.h new file mode 100644 index 0000000..65dc14c --- /dev/null +++ b/WebKit/chromium/src/DebuggerAgentImpl.h @@ -0,0 +1,103 @@ +/* + * 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 DebuggerAgentImpl_h +#define DebuggerAgentImpl_h + +#include "DebuggerAgent.h" + +#include <v8.h> +#include <wtf/HashSet.h> +#include <wtf/Noncopyable.h> + +namespace WebCore { +class Document; +class Frame; +class Node; +class Page; +class String; +} + +namespace WebKit { + +class WebDevToolsAgentImpl; +class WebViewImpl; + +class DebuggerAgentImpl : public DebuggerAgent { +public: + // Creates utility context with injected js agent. + static void createUtilityContext(WebCore::Frame* frame, v8::Persistent<v8::Context>* context); + + DebuggerAgentImpl(WebKit::WebViewImpl* webViewImpl, + DebuggerAgentDelegate* delegate, + WebDevToolsAgentImpl* webdevtoolsAgent); + virtual ~DebuggerAgentImpl(); + + // DebuggerAgent implementation. + virtual void getContextId(); + + void debuggerOutput(const WebCore::String& out); + + void setAutoContinueOnException(bool autoContinue) { m_autoContinueOnException = autoContinue; } + + bool autoContinueOnException() { return m_autoContinueOnException; } + + // Executes function with the given name in the utility context. Passes node + // and json args as parameters. Note that the function called must be + // implemented in the inject_dispatch.js file. + WebCore::String executeUtilityFunction( + v8::Handle<v8::Context> context, + int callId, + const char* object, + const WebCore::String& functionName, + const WebCore::String& jsonArgs, + 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; } + + WebKit::WebViewImpl* webView() { return m_webViewImpl; } + +private: + WebKit::WebViewImpl* m_webViewImpl; + DebuggerAgentDelegate* m_delegate; + WebDevToolsAgentImpl* m_webdevtoolsAgent; + bool m_autoContinueOnException; +}; + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/DebuggerAgentManager.cpp b/WebKit/chromium/src/DebuggerAgentManager.cpp new file mode 100644 index 0000000..faafaff --- /dev/null +++ b/WebKit/chromium/src/DebuggerAgentManager.cpp @@ -0,0 +1,311 @@ +/* + * 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 "DebuggerAgentManager.h" + +#include "DebuggerAgentImpl.h" +#include "Frame.h" +#include "PageGroupLoadDeferrer.h" +#include "V8Proxy.h" +#include "WebDevToolsAgentImpl.h" +#include "WebFrameImpl.h" +#include "WebViewImpl.h" +#include <wtf/HashSet.h> +#include <wtf/Noncopyable.h> + +namespace WebKit { + +WebDevToolsAgent::MessageLoopDispatchHandler DebuggerAgentManager::s_messageLoopDispatchHandler = 0; + +bool DebuggerAgentManager::s_inHostDispatchHandler = false; + +DebuggerAgentManager::DeferrersMap DebuggerAgentManager::s_pageDeferrers; + +bool DebuggerAgentManager::s_inUtilityContext = false; + +bool DebuggerAgentManager::s_debugBreakDelayed = false; + +namespace { + +class CallerIdWrapper : public v8::Debug::ClientData, public Noncopyable { +public: + CallerIdWrapper() : m_callerIsMananager(true), m_callerId(0) { } + explicit CallerIdWrapper(int callerId) + : m_callerIsMananager(false) + , m_callerId(callerId) { } + ~CallerIdWrapper() { } + bool callerIsMananager() const { return m_callerIsMananager; } + int callerId() const { return m_callerId; } +private: + bool m_callerIsMananager; + int m_callerId; +}; + +} // namespace + + +void DebuggerAgentManager::debugHostDispatchHandler() +{ + if (!s_messageLoopDispatchHandler || !s_attachedAgentsMap) + return; + + if (s_inHostDispatchHandler) + return; + + s_inHostDispatchHandler = true; + + Vector<WebViewImpl*> views; + // 1. Disable active objects and input events. + for (AttachedAgentsMap::iterator it = s_attachedAgentsMap->begin(); it != s_attachedAgentsMap->end(); ++it) { + DebuggerAgentImpl* agent = it->second; + s_pageDeferrers.set(agent->webView(), new WebCore::PageGroupLoadDeferrer(agent->page(), true)); + views.append(agent->webView()); + agent->webView()->setIgnoreInputEvents(true); + } + + // 2. Process messages. + s_messageLoopDispatchHandler(); + + // 3. Bring things back. + for (Vector<WebViewImpl*>::iterator it = views.begin(); it != views.end(); ++it) { + if (s_pageDeferrers.contains(*it)) { + // The view was not closed during the dispatch. + (*it)->setIgnoreInputEvents(false); + } + } + deleteAllValues(s_pageDeferrers); + s_pageDeferrers.clear(); + + s_inHostDispatchHandler = false; + if (!s_attachedAgentsMap) { + // Remove handlers if all agents were detached within host dispatch. + v8::Debug::SetMessageHandler(0); + v8::Debug::SetHostDispatchHandler(0); + } +} + +DebuggerAgentManager::AttachedAgentsMap* DebuggerAgentManager::s_attachedAgentsMap = 0; + +void DebuggerAgentManager::debugAttach(DebuggerAgentImpl* debuggerAgent) +{ + if (!s_attachedAgentsMap) { + s_attachedAgentsMap = new AttachedAgentsMap(); + v8::Debug::SetMessageHandler2(&DebuggerAgentManager::onV8DebugMessage); + v8::Debug::SetHostDispatchHandler(&DebuggerAgentManager::debugHostDispatchHandler, 100 /* ms */); + } + int hostId = debuggerAgent->webdevtoolsAgent()->hostId(); + ASSERT(hostId); + s_attachedAgentsMap->set(hostId, debuggerAgent); +} + +void DebuggerAgentManager::debugDetach(DebuggerAgentImpl* debuggerAgent) +{ + if (!s_attachedAgentsMap) { + ASSERT_NOT_REACHED(); + return; + } + int hostId = debuggerAgent->webdevtoolsAgent()->hostId(); + ASSERT(s_attachedAgentsMap->get(hostId) == debuggerAgent); + bool isOnBreakpoint = (findAgentForCurrentV8Context() == debuggerAgent); + s_attachedAgentsMap->remove(hostId); + + if (s_attachedAgentsMap->isEmpty()) { + delete s_attachedAgentsMap; + s_attachedAgentsMap = 0; + // Note that we do not empty handlers while in dispatch - we schedule + // continue and do removal once we are out of the dispatch. Also there is + // no need to send continue command in this case since removing message + // handler will cause debugger unload and all breakpoints will be cleared. + if (!s_inHostDispatchHandler) { + v8::Debug::SetMessageHandler2(0); + v8::Debug::SetHostDispatchHandler(0); + } + } else { + // Remove all breakpoints set by the agent. + String clearBreakpointGroupCmd = String::format( + "{\"seq\":1,\"type\":\"request\",\"command\":\"clearbreakpointgroup\"," + "\"arguments\":{\"groupId\":%d}}", + hostId); + sendCommandToV8(clearBreakpointGroupCmd, new CallerIdWrapper()); + + if (isOnBreakpoint) { + // Force continue if detach happened in nessted message loop while + // debugger was paused on a breakpoint(as long as there are other + // attached agents v8 will wait for explicit'continue' message). + sendContinueCommandToV8(); + } + } +} + +void DebuggerAgentManager::onV8DebugMessage(const v8::Debug::Message& message) +{ + v8::HandleScope scope; + v8::String::Value value(message.GetJSON()); + String out(reinterpret_cast<const UChar*>(*value), value.length()); + + // If callerData is not 0 the message is a response to a debugger command. + if (v8::Debug::ClientData* callerData = message.GetClientData()) { + CallerIdWrapper* wrapper = static_cast<CallerIdWrapper*>(callerData); + if (wrapper->callerIsMananager()) { + // Just ignore messages sent by this manager. + return; + } + DebuggerAgentImpl* debuggerAgent = debuggerAgentForHostId(wrapper->callerId()); + if (debuggerAgent) + debuggerAgent->debuggerOutput(out); + else if (!message.WillStartRunning()) { + // Autocontinue execution if there is no handler. + sendContinueCommandToV8(); + } + return; + } // Otherwise it's an event message. + ASSERT(message.IsEvent()); + + // Ignore unsupported event types. + if (message.GetEvent() != v8::AfterCompile && message.GetEvent() != v8::Break && message.GetEvent() != v8::Exception) + return; + + v8::Handle<v8::Context> context = message.GetEventContext(); + // If the context is from one of the inpected tabs it should have its context + // data. + if (context.IsEmpty()) { + // Unknown context, skip the event. + return; + } + + if (s_inUtilityContext && message.GetEvent() == v8::Break) { + // This may happen when two tabs are being debugged in the same process. + // Suppose that first debugger is pauesed on an exception. It will run + // nested MessageLoop which may process Break request from the second + // debugger. + s_debugBreakDelayed = true; + } else { + // If the context is from one of the inpected tabs or injected extension + // scripts it must have hostId in the data field. + int hostId = WebCore::V8Proxy::contextDebugId(context); + if (hostId != -1) { + DebuggerAgentImpl* agent = debuggerAgentForHostId(hostId); + if (agent) { + if (agent->autoContinueOnException() + && message.GetEvent() == v8::Exception) { + sendContinueCommandToV8(); + return; + } + + agent->debuggerOutput(out); + return; + } + } + } + + if (!message.WillStartRunning()) { + // Autocontinue execution on break and exception events if there is no + // handler. + sendContinueCommandToV8(); + } +} + +void DebuggerAgentManager::pauseScript() +{ + if (s_inUtilityContext) + s_debugBreakDelayed = true; + else + v8::Debug::DebugBreak(); +} + +void DebuggerAgentManager::executeDebuggerCommand(const String& command, int callerId) +{ + sendCommandToV8(command, new CallerIdWrapper(callerId)); +} + +void DebuggerAgentManager::setMessageLoopDispatchHandler(WebDevToolsAgent::MessageLoopDispatchHandler handler) +{ + s_messageLoopDispatchHandler = handler; +} + +void DebuggerAgentManager::setHostId(WebFrameImpl* webframe, int hostId) +{ + ASSERT(hostId > 0); + WebCore::V8Proxy* proxy = WebCore::V8Proxy::retrieve(webframe->frame()); + if (proxy) + proxy->setContextDebugId(hostId); +} + +void DebuggerAgentManager::onWebViewClosed(WebViewImpl* webview) +{ + if (s_pageDeferrers.contains(webview)) { + delete s_pageDeferrers.get(webview); + s_pageDeferrers.remove(webview); + } +} + +void DebuggerAgentManager::onNavigate() +{ + if (s_inHostDispatchHandler) + DebuggerAgentManager::sendContinueCommandToV8(); +} + +void DebuggerAgentManager::sendCommandToV8(const String& cmd, v8::Debug::ClientData* data) +{ + v8::Debug::SendCommand(reinterpret_cast<const uint16_t*>(cmd.characters()), cmd.length(), data); +} + +void DebuggerAgentManager::sendContinueCommandToV8() +{ + String continueCmd("{\"seq\":1,\"type\":\"request\",\"command\":\"continue\"}"); + sendCommandToV8(continueCmd, new CallerIdWrapper()); +} + +DebuggerAgentImpl* DebuggerAgentManager::findAgentForCurrentV8Context() +{ + if (!s_attachedAgentsMap) + return 0; + ASSERT(!s_attachedAgentsMap->isEmpty()); + + WebCore::Frame* frame = WebCore::V8Proxy::retrieveFrameForEnteredContext(); + if (!frame) + return 0; + WebCore::Page* page = frame->page(); + for (AttachedAgentsMap::iterator it = s_attachedAgentsMap->begin(); it != s_attachedAgentsMap->end(); ++it) { + if (it->second->page() == page) + return it->second; + } + return 0; +} + +DebuggerAgentImpl* DebuggerAgentManager::debuggerAgentForHostId(int hostId) +{ + if (!s_attachedAgentsMap) + return 0; + return s_attachedAgentsMap->get(hostId); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/DebuggerAgentManager.h b/WebKit/chromium/src/DebuggerAgentManager.h new file mode 100644 index 0000000..a2e9030 --- /dev/null +++ b/WebKit/chromium/src/DebuggerAgentManager.h @@ -0,0 +1,123 @@ +/* + * 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 DebuggerAgentManager_h +#define DebuggerAgentManager_h + +#include "WebDevToolsAgent.h" +#include <v8-debug.h> +#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> + +namespace WebCore { +class PageGroupLoadDeferrer; +class String; +} + +namespace WebKit { + +class DebuggerAgentImpl; +class DictionaryValue; +class WebFrameImpl; +class WebViewImpl; + +// There is single v8 instance per render process. Also there may be several +// RenderViews and consequently devtools agents in the process that want to talk +// to the v8 debugger. This class coordinates communication between the debug +// agents and v8 debugger. It will set debug output handler as long as at least +// one debugger agent is attached and remove it when last debugger agent is +// detached. When message is received from debugger it will route it to the +// right debugger agent if there is one otherwise the message will be ignored. +// +// v8 may send a message(e.g. exception event) after which it +// would expect some actions from the handler. If there is no appropriate +// debugger agent to handle such messages the manager will perform the action +// itself, otherwise v8 may hang waiting for the action. +class DebuggerAgentManager : public Noncopyable { +public: + static void debugAttach(DebuggerAgentImpl* debuggerAgent); + static void debugDetach(DebuggerAgentImpl* debuggerAgent); + static void pauseScript(); + static void executeDebuggerCommand(const WebCore::String& command, int callerId); + static void setMessageLoopDispatchHandler(WebDevToolsAgent::MessageLoopDispatchHandler handler); + + // Sets |hostId| as the frame context data. This id is used to filter scripts + // related to the inspected page. + static void setHostId(WebFrameImpl* webframe, int hostId); + + static void onWebViewClosed(WebViewImpl* webview); + + static void onNavigate(); + + class UtilityContextScope : public Noncopyable { + public: + UtilityContextScope() + { + ASSERT(!s_inUtilityContext); + s_inUtilityContext = true; + } + ~UtilityContextScope() + { + if (s_debugBreakDelayed) { + v8::Debug::DebugBreak(); + s_debugBreakDelayed = false; + } + s_inUtilityContext = false; + } + }; + +private: + DebuggerAgentManager(); + ~DebuggerAgentManager(); + + static void debugHostDispatchHandler(); + static void onV8DebugMessage(const v8::Debug::Message& message); + static void sendCommandToV8(const WebCore::String& cmd, + v8::Debug::ClientData* data); + static void sendContinueCommandToV8(); + + static DebuggerAgentImpl* findAgentForCurrentV8Context(); + static DebuggerAgentImpl* debuggerAgentForHostId(int hostId); + + typedef HashMap<int, DebuggerAgentImpl*> AttachedAgentsMap; + static AttachedAgentsMap* s_attachedAgentsMap; + + static WebDevToolsAgent::MessageLoopDispatchHandler s_messageLoopDispatchHandler; + static bool s_inHostDispatchHandler; + typedef HashMap<WebViewImpl*, WebCore::PageGroupLoadDeferrer*> DeferrersMap; + static DeferrersMap s_pageDeferrers; + + static bool s_inUtilityContext; + static bool s_debugBreakDelayed; +}; + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/DevToolsRPC.h b/WebKit/chromium/src/DevToolsRPC.h new file mode 100644 index 0000000..7176821 --- /dev/null +++ b/WebKit/chromium/src/DevToolsRPC.h @@ -0,0 +1,396 @@ +/* + * 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. + */ + +// DevTools RPC subsystem is a simple string serialization-based rpc +// implementation. The client is responsible for defining the Rpc-enabled +// interface in terms of its macros: +// +// #define MYAPI_STRUCT(METHOD0, METHOD1, METHOD2, METHOD3) +// METHOD0(Method1) +// METHOD1(Method3, int) +// (snippet above should be multiline macro, add trailing backslashes) +// +// DEFINE_RPC_CLASS(MyApi, MYAPI_STRUCT) +// +// The snippet above will generate three classes: MyApi, MyApiStub and +// MyApiDispatch. +// +// 1. For each method defined in the marco MyApi will have a +// pure virtual function generated, so that MyApi would look like: +// +// class MyApi { +// private: +// MyApi() { } +// ~MyApi() { } +// virtual void method1() = 0; +// virtual void method2( +// int param1, +// const String& param2, +// const Value& param3) = 0; +// virtual void method3(int param1) = 0; +// }; +// +// 2. MyApiStub will implement MyApi interface and would serialize all calls +// into the string-based calls of the underlying transport: +// +// DevToolsRPC::Delegate* transport; +// myApi = new MyApiStub(transport); +// myApi->method1(); +// myApi->method3(2); +// +// 3. MyApiDelegate is capable of dispatching the calls and convert them to the +// calls to the underlying MyApi methods: +// +// MyApi* realObject; +// MyApiDispatch::dispatch(realObject, rawStringCallGeneratedByStub); +// +// will make corresponding calls to the real object. + +#ifndef DevToolsRPC_h +#define DevToolsRPC_h + +#include "PlatformString.h" +#include "Vector.h" +#include "WebDevToolsMessageData.h" + +#include <wtf/Noncopyable.h> + +namespace WebCore { +class String; +} + +using WebCore::String; +using WTF::Vector; + +namespace WebKit { + +/////////////////////////////////////////////////////// +// RPC dispatch macro + +template<typename T> +struct RpcTypeTrait { + typedef T ApiType; +}; + +template<> +struct RpcTypeTrait<bool> { + typedef bool ApiType; + static bool parse(const WebCore::String& t) + { + return t == "true"; + } + static WebCore::String toString(bool b) + { + return b ? "true" : "false"; + } +}; + +template<> +struct RpcTypeTrait<int> { + typedef int ApiType; + static int parse(const WebCore::String& t) + { + bool success; + int i = t.toIntStrict(&success); + ASSERT(success); + return i; + } + static WebCore::String toString(int i) + { + return WebCore::String::number(i); + } +}; + +template<> +struct RpcTypeTrait<String> { + typedef const String& ApiType; + static String parse(const WebCore::String& t) + { + return t; + } + static WebCore::String toString(const String& t) + { + return t; + } +}; + +/////////////////////////////////////////////////////// +// RPC Api method declarations + +#define TOOLS_RPC_API_METHOD0(Method) \ + virtual void Method() = 0; + +#define TOOLS_RPC_API_METHOD1(Method, T1) \ + virtual void Method(RpcTypeTrait<T1>::ApiType t1) = 0; + +#define TOOLS_RPC_API_METHOD2(Method, T1, T2) \ + virtual void Method(RpcTypeTrait<T1>::ApiType t1, \ + RpcTypeTrait<T2>::ApiType t2) = 0; + +#define TOOLS_RPC_API_METHOD3(Method, T1, T2, T3) \ + virtual void Method(RpcTypeTrait<T1>::ApiType t1, \ + RpcTypeTrait<T2>::ApiType t2, \ + RpcTypeTrait<T3>::ApiType t3) = 0; + +#define TOOLS_RPC_API_METHOD4(Method, T1, T2, T3, T4) \ + virtual void Method(RpcTypeTrait<T1>::ApiType t1, \ + RpcTypeTrait<T2>::ApiType t2, \ + RpcTypeTrait<T3>::ApiType t3, \ + RpcTypeTrait<T4>::ApiType t4) = 0; + +#define TOOLS_RPC_API_METHOD5(Method, T1, T2, T3, T4, T5) \ + virtual void Method(RpcTypeTrait<T1>::ApiType t1, \ + RpcTypeTrait<T2>::ApiType t2, \ + RpcTypeTrait<T3>::ApiType t3, \ + RpcTypeTrait<T4>::ApiType t4, \ + RpcTypeTrait<T5>::ApiType t5) = 0; + +/////////////////////////////////////////////////////// +// RPC stub method implementations + +#define TOOLS_RPC_STUB_METHOD0(Method) \ + virtual void Method() { \ + Vector<String> args; \ + this->sendRpcMessage(m_className, #Method, args); \ + } + +#define TOOLS_RPC_STUB_METHOD1(Method, T1) \ + virtual void Method(RpcTypeTrait<T1>::ApiType t1) { \ + Vector<String> args(1); \ + args[0] = RpcTypeTrait<T1>::toString(t1); \ + this->sendRpcMessage(m_className, #Method, args); \ + } + +#define TOOLS_RPC_STUB_METHOD2(Method, T1, T2) \ + virtual void Method(RpcTypeTrait<T1>::ApiType t1, \ + RpcTypeTrait<T2>::ApiType t2) { \ + Vector<String> args(2); \ + args[0] = RpcTypeTrait<T1>::toString(t1); \ + args[1] = RpcTypeTrait<T2>::toString(t2); \ + this->sendRpcMessage(m_className, #Method, args); \ + } + +#define TOOLS_RPC_STUB_METHOD3(Method, T1, T2, T3) \ + virtual void Method(RpcTypeTrait<T1>::ApiType t1, \ + RpcTypeTrait<T2>::ApiType t2, \ + RpcTypeTrait<T3>::ApiType t3) { \ + Vector<String> args(3); \ + args[0] = RpcTypeTrait<T1>::toString(t1); \ + args[1] = RpcTypeTrait<T2>::toString(t2); \ + args[2] = RpcTypeTrait<T3>::toString(t3); \ + this->sendRpcMessage(m_className, #Method, args); \ + } + +#define TOOLS_RPC_STUB_METHOD4(Method, T1, T2, T3, T4) \ + virtual void Method(RpcTypeTrait<T1>::ApiType t1, \ + RpcTypeTrait<T2>::ApiType t2, \ + RpcTypeTrait<T3>::ApiType t3, \ + RpcTypeTrait<T4>::ApiType t4) { \ + Vector<String> args(4); \ + args[0] = RpcTypeTrait<T1>::toString(t1); \ + args[1] = RpcTypeTrait<T2>::toString(t2); \ + args[2] = RpcTypeTrait<T3>::toString(t3); \ + args[3] = RpcTypeTrait<T4>::toString(t4); \ + this->sendRpcMessage(m_className, #Method, args); \ + } + +#define TOOLS_RPC_STUB_METHOD5(Method, T1, T2, T3, T4, T5) \ + virtual void Method(RpcTypeTrait<T1>::ApiType t1, \ + RpcTypeTrait<T2>::ApiType t2, \ + RpcTypeTrait<T3>::ApiType t3, \ + RpcTypeTrait<T4>::ApiType t4, \ + RpcTypeTrait<T5>::ApiType t5) { \ + Vector<String> args(5); \ + args[0] = RpcTypeTrait<T1>::toString(t1); \ + args[1] = RpcTypeTrait<T2>::toString(t2); \ + args[2] = RpcTypeTrait<T3>::toString(t3); \ + args[3] = RpcTypeTrait<T4>::toString(t4); \ + args[4] = RpcTypeTrait<T5>::toString(t5); \ + this->sendRpcMessage(m_className, #Method, args); \ + } + +/////////////////////////////////////////////////////// +// RPC dispatch method implementations + +#define TOOLS_RPC_DISPATCH0(Method) \ +if (methodName == #Method) { \ + delegate->Method(); \ + return true; \ +} + +#define TOOLS_RPC_DISPATCH1(Method, T1) \ +if (methodName == #Method) { \ + delegate->Method(RpcTypeTrait<T1>::parse(args[0])); \ + return true; \ +} + +#define TOOLS_RPC_DISPATCH2(Method, T1, T2) \ +if (methodName == #Method) { \ + delegate->Method( \ + RpcTypeTrait<T1>::parse(args[0]), \ + RpcTypeTrait<T2>::parse(args[1]) \ + ); \ + return true; \ +} + +#define TOOLS_RPC_DISPATCH3(Method, T1, T2, T3) \ +if (methodName == #Method) { \ + delegate->Method( \ + RpcTypeTrait<T1>::parse(args[0]), \ + RpcTypeTrait<T2>::parse(args[1]), \ + RpcTypeTrait<T3>::parse(args[2]) \ + ); \ + return true; \ +} + +#define TOOLS_RPC_DISPATCH4(Method, T1, T2, T3, T4) \ +if (methodName == #Method) { \ + delegate->Method( \ + RpcTypeTrait<T1>::parse(args[0]), \ + RpcTypeTrait<T2>::parse(args[1]), \ + RpcTypeTrait<T3>::parse(args[2]), \ + RpcTypeTrait<T4>::parse(args[3]) \ + ); \ + return true; \ +} + +#define TOOLS_RPC_DISPATCH5(Method, T1, T2, T3, T4, T5) \ +if (methodName == #Method) { \ + delegate->Method( \ + RpcTypeTrait<T1>::parse(args[0]), \ + RpcTypeTrait<T2>::parse(args[1]), \ + RpcTypeTrait<T3>::parse(args[2]), \ + RpcTypeTrait<T4>::parse(args[3]), \ + RpcTypeTrait<T5>::parse(args[4]) \ + ); \ + return true; \ +} + +#define TOOLS_END_RPC_DISPATCH() \ +} + +// This macro defines three classes: Class with the Api, ClassStub that is +// serializing method calls and ClassDispatch that is capable of dispatching +// the serialized message into its delegate. +#define DEFINE_RPC_CLASS(Class, STRUCT) \ +class Class : public Noncopyable {\ +public: \ + Class() \ + { \ + m_className = #Class; \ + } \ + virtual ~Class() { } \ + \ + STRUCT( \ + TOOLS_RPC_API_METHOD0, \ + TOOLS_RPC_API_METHOD1, \ + TOOLS_RPC_API_METHOD2, \ + TOOLS_RPC_API_METHOD3, \ + TOOLS_RPC_API_METHOD4, \ + TOOLS_RPC_API_METHOD5) \ + WebCore::String m_className; \ +}; \ +\ +class Class##Stub \ + : public Class \ + , public DevToolsRPC { \ +public: \ + explicit Class##Stub(Delegate* delegate) : DevToolsRPC(delegate) { } \ + virtual ~Class##Stub() { } \ + typedef Class CLASS; \ + STRUCT( \ + TOOLS_RPC_STUB_METHOD0, \ + TOOLS_RPC_STUB_METHOD1, \ + TOOLS_RPC_STUB_METHOD2, \ + TOOLS_RPC_STUB_METHOD3, \ + TOOLS_RPC_STUB_METHOD4, \ + TOOLS_RPC_STUB_METHOD5) \ +}; \ +\ +class Class##Dispatch : public Noncopyable { \ +public: \ + Class##Dispatch() { } \ + virtual ~Class##Dispatch() { } \ + \ + static bool dispatch(Class* delegate, \ + const WebKit::WebDevToolsMessageData& data) { \ + String className = data.className; \ + if (className != #Class) \ + return false; \ + String methodName = data.methodName; \ + Vector<String> args; \ + for (size_t i = 0; i < data.arguments.size(); i++) \ + args.append(data.arguments[i]); \ + typedef Class CLASS; \ + STRUCT( \ + TOOLS_RPC_DISPATCH0, \ + TOOLS_RPC_DISPATCH1, \ + TOOLS_RPC_DISPATCH2, \ + TOOLS_RPC_DISPATCH3, \ + TOOLS_RPC_DISPATCH4, \ + TOOLS_RPC_DISPATCH5) \ + return false; \ + } \ +}; + +/////////////////////////////////////////////////////// +// RPC base class +class DevToolsRPC { +public: + class Delegate { + public: + Delegate() { } + virtual ~Delegate() { } + virtual void sendRpcMessage(const WebKit::WebDevToolsMessageData& data) = 0; + }; + + explicit DevToolsRPC(Delegate* delegate) : m_delegate(delegate) { } + virtual ~DevToolsRPC() { }; + +protected: + void sendRpcMessage(const String& className, + const String& methodName, + const Vector<String>& args) { + WebKit::WebVector<WebKit::WebString> webArgs(args.size()); + for (size_t i = 0; i < args.size(); i++) + webArgs[i] = args[i]; + WebKit::WebDevToolsMessageData data; + data.className = className; + data.methodName = methodName; + data.arguments.swap(webArgs); + this->m_delegate->sendRpcMessage(data); + } + + Delegate* m_delegate; +}; + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/DevToolsRPCJS.h b/WebKit/chromium/src/DevToolsRPCJS.h new file mode 100644 index 0000000..8ae279f --- /dev/null +++ b/WebKit/chromium/src/DevToolsRPCJS.h @@ -0,0 +1,147 @@ +/* + * 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. + */ + +// Additional set of macros for the JS RPC. + +#ifndef DevToolsRPCJS_h +#define DevToolsRPCJS_h + +// Do not remove this one although it is not used. +#include "BoundObject.h" +#include "DevToolsRPC.h" +#include "WebFrame.h" +#include <wtf/Noncopyable.h> +#include <wtf/OwnPtr.h> + +namespace WebKit { + +/////////////////////////////////////////////////////// +// JS RPC binds and stubs + +#define TOOLS_RPC_JS_BIND_METHOD0(Method) \ + boundObj.addProtoFunction(#Method, OCLASS::js##Method); + +#define TOOLS_RPC_JS_BIND_METHOD1(Method, T1) \ + boundObj.addProtoFunction(#Method, OCLASS::js##Method); + +#define TOOLS_RPC_JS_BIND_METHOD2(Method, T1, T2) \ + boundObj.addProtoFunction(#Method, OCLASS::js##Method); + +#define TOOLS_RPC_JS_BIND_METHOD3(Method, T1, T2, T3) \ + boundObj.addProtoFunction(#Method, OCLASS::js##Method); + +#define TOOLS_RPC_JS_BIND_METHOD4(Method, T1, T2, T3, T4) \ + boundObj.addProtoFunction(#Method, OCLASS::js##Method); + +#define TOOLS_RPC_JS_BIND_METHOD5(Method, T1, T2, T3, T4, T5) \ + boundObj.addProtoFunction(#Method, OCLASS::js##Method); + +#define TOOLS_RPC_JS_STUB_METHOD0(Method) \ + static v8::Handle<v8::Value> js##Method(const v8::Arguments& args) { \ + sendRpcMessageFromJS(#Method, args, 0); \ + return v8::Undefined(); \ + } + +#define TOOLS_RPC_JS_STUB_METHOD1(Method, T1) \ + static v8::Handle<v8::Value> js##Method(const v8::Arguments& args) { \ + sendRpcMessageFromJS(#Method, args, 1); \ + return v8::Undefined(); \ + } + +#define TOOLS_RPC_JS_STUB_METHOD2(Method, T1, T2) \ + static v8::Handle<v8::Value> js##Method(const v8::Arguments& args) { \ + sendRpcMessageFromJS(#Method, args, 2); \ + return v8::Undefined(); \ + } + +#define TOOLS_RPC_JS_STUB_METHOD3(Method, T1, T2, T3) \ + static v8::Handle<v8::Value> js##Method(const v8::Arguments& args) { \ + sendRpcMessageFromJS(#Method, args, 3); \ + return v8::Undefined(); \ + } + +#define TOOLS_RPC_JS_STUB_METHOD4(Method, T1, T2, T3, T4) \ + static v8::Handle<v8::Value> js##Method(const v8::Arguments& args) { \ + sendRpcMessageFromJS(#Method, args, 4); \ + return v8::Undefined(); \ + } + +#define TOOLS_RPC_JS_STUB_METHOD5(Method, T1, T2, T3, T4, T5) \ + static v8::Handle<v8::Value> js##Method(const v8::Arguments& args) { \ + sendRpcMessageFromJS(#Method, args, 5); \ + return v8::Undefined(); \ + } + +/////////////////////////////////////////////////////// +// JS RPC main obj macro + +#define DEFINE_RPC_JS_BOUND_OBJ(Class, STRUCT, DClass, DELEGATE_STRUCT) \ +class JS##Class##BoundObj : public Class##Stub { \ +public: \ + JS##Class##BoundObj(Delegate* rpcDelegate, \ + v8::Handle<v8::Context> context, \ + const char* classname) \ + : Class##Stub(rpcDelegate) { \ + BoundObject boundObj(context, this, classname); \ + STRUCT( \ + TOOLS_RPC_JS_BIND_METHOD0, \ + TOOLS_RPC_JS_BIND_METHOD1, \ + TOOLS_RPC_JS_BIND_METHOD2, \ + TOOLS_RPC_JS_BIND_METHOD3, \ + TOOLS_RPC_JS_BIND_METHOD4, \ + TOOLS_RPC_JS_BIND_METHOD5) \ + boundObj.build(); \ + } \ + virtual ~JS##Class##BoundObj() { } \ + typedef JS##Class##BoundObj OCLASS; \ + STRUCT( \ + TOOLS_RPC_JS_STUB_METHOD0, \ + TOOLS_RPC_JS_STUB_METHOD1, \ + TOOLS_RPC_JS_STUB_METHOD2, \ + TOOLS_RPC_JS_STUB_METHOD3, \ + TOOLS_RPC_JS_STUB_METHOD4, \ + TOOLS_RPC_JS_STUB_METHOD5) \ +private: \ + static void sendRpcMessageFromJS(const char* method, \ + const v8::Arguments& jsArguments, \ + size_t argsCount) \ + { \ + Vector<String> args(argsCount); \ + for (size_t i = 0; i < argsCount; i++) \ + args[i] = WebCore::toWebCoreStringWithNullCheck(jsArguments[i]); \ + void* selfPtr = v8::External::Cast(*jsArguments.Data())->Value(); \ + JS##Class##BoundObj* self = static_cast<JS##Class##BoundObj*>(selfPtr); \ + self->sendRpcMessage(#Class, method, args); \ + } \ +}; + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/ProfilerAgent.h b/WebKit/chromium/src/ProfilerAgent.h new file mode 100644 index 0000000..52337b8 --- /dev/null +++ b/WebKit/chromium/src/ProfilerAgent.h @@ -0,0 +1,61 @@ +/* + * 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 ProfilerAgent_h +#define ProfilerAgent_h + +#include "DevToolsRPC.h" + +namespace WebKit { + +// Profiler agent provides API for retrieving profiler data. +// These methods are handled on the IO thread, so profiler can +// operate while a script on a page performs heavy work. +#define PROFILER_AGENT_STRUCT(METHOD0, METHOD1, METHOD2, METHOD3, METHOD4, METHOD5) \ + /* Requests current profiler state. */ \ + METHOD0(getActiveProfilerModules) \ + \ + /* Retrieves portion of profiler log. */ \ + METHOD1(getLogLines, int /* position */) + +DEFINE_RPC_CLASS(ProfilerAgent, PROFILER_AGENT_STRUCT) + +#define PROFILER_AGENT_DELEGATE_STRUCT(METHOD0, METHOD1, METHOD2, METHOD3, METHOD4, METHOD5) \ + /* Response to getActiveProfilerModules. */ \ + METHOD1(didGetActiveProfilerModules, int /* flags */) \ + \ + /* Response to getLogLines. */ \ + METHOD2(didGetLogLines, int /* position */, String /* log */) + +DEFINE_RPC_CLASS(ProfilerAgentDelegate, PROFILER_AGENT_DELEGATE_STRUCT) + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/ProfilerAgentImpl.cpp b/WebKit/chromium/src/ProfilerAgentImpl.cpp new file mode 100644 index 0000000..07570df --- /dev/null +++ b/WebKit/chromium/src/ProfilerAgentImpl.cpp @@ -0,0 +1,52 @@ +/* + * 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 "ProfilerAgentImpl.h" + +#include <v8.h> + +namespace WebKit { + +void ProfilerAgentImpl::getActiveProfilerModules() +{ + m_delegate->didGetActiveProfilerModules(v8::V8::GetActiveProfilerModules()); +} + +void ProfilerAgentImpl::getLogLines(int position) +{ + static char buffer[65536]; + const int readSize = v8::V8::GetLogLines(position, buffer, sizeof(buffer) - 1); + buffer[readSize] = '\0'; + position += readSize; + m_delegate->didGetLogLines(position, buffer); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/ProfilerAgentImpl.h b/WebKit/chromium/src/ProfilerAgentImpl.h new file mode 100644 index 0000000..d38f57c --- /dev/null +++ b/WebKit/chromium/src/ProfilerAgentImpl.h @@ -0,0 +1,57 @@ +/* + * 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 ProfilerAgentImpl_h +#define ProfilerAgentImpl_h + +#include "ProfilerAgent.h" + +namespace WebKit { + +class ProfilerAgentImpl : public ProfilerAgent { +public: + ProfilerAgentImpl(ProfilerAgentDelegate* delegate) : m_delegate(delegate) { } + virtual ~ProfilerAgentImpl() { } + + // ProfilerAgent implementation. + + // This method is called on IO thread. + virtual void getActiveProfilerModules(); + + // This method is called on IO thread. + virtual void getLogLines(int position); + +private: + ProfilerAgentDelegate* m_delegate; +}; + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/SharedWorkerRepository.cpp b/WebKit/chromium/src/SharedWorkerRepository.cpp index 5e5bc46..c803aac 100644 --- a/WebKit/chromium/src/SharedWorkerRepository.cpp +++ b/WebKit/chromium/src/SharedWorkerRepository.cpp @@ -61,26 +61,30 @@ using WebKit::WebSharedWorker; using WebKit::WebSharedWorkerRepository; // Callback class that keeps the SharedWorker and WebSharedWorker objects alive while loads are potentially happening, and also translates load errors into error events on the worker. -class SharedWorkerScriptLoader : private WorkerScriptLoaderClient, private WebSharedWorker::ConnectListener, private ActiveDOMObject { +class SharedWorkerScriptLoader : private WorkerScriptLoaderClient, private WebSharedWorker::ConnectListener { public: SharedWorkerScriptLoader(PassRefPtr<SharedWorker> worker, const KURL& url, const String& name, PassOwnPtr<MessagePortChannel> port, PassOwnPtr<WebSharedWorker> webWorker) - : ActiveDOMObject(worker->scriptExecutionContext(), this) - , m_worker(worker) + : m_worker(worker) , m_url(url) , m_name(name) , m_webWorker(webWorker) , m_port(port) + , m_loading(false) { } + ~SharedWorkerScriptLoader(); void load(); - virtual void contextDestroyed(); + static void stopAllLoadersForContext(ScriptExecutionContext*); + private: // WorkerScriptLoaderClient callback virtual void notifyFinished(); virtual void connected(); + const ScriptExecutionContext* loadingContext() { return m_worker->scriptExecutionContext(); } + void sendConnect(); RefPtr<SharedWorker> m_worker; @@ -89,15 +93,47 @@ private: OwnPtr<WebSharedWorker> m_webWorker; OwnPtr<MessagePortChannel> m_port; WorkerScriptLoader m_scriptLoader; + bool m_loading; }; +static Vector<SharedWorkerScriptLoader*>& pendingLoaders() +{ + AtomicallyInitializedStatic(Vector<SharedWorkerScriptLoader*>&, loaders = *new Vector<SharedWorkerScriptLoader*>); + return loaders; +} + +void SharedWorkerScriptLoader::stopAllLoadersForContext(ScriptExecutionContext* context) +{ + // Walk our list of pending loaders and shutdown any that belong to this context. + Vector<SharedWorkerScriptLoader*>& loaders = pendingLoaders(); + for (unsigned i = 0; i < loaders.size(); ) { + SharedWorkerScriptLoader* loader = loaders[i]; + if (context == loader->loadingContext()) { + loaders.remove(i); + delete loader; + } else + i++; + } +} + +SharedWorkerScriptLoader::~SharedWorkerScriptLoader() +{ + if (m_loading) + m_worker->unsetPendingActivity(m_worker.get()); +} + void SharedWorkerScriptLoader::load() { + ASSERT(!m_loading); // If the shared worker is not yet running, load the script resource for it, otherwise just send it a connect event. if (m_webWorker->isStarted()) sendConnect(); - else + else { m_scriptLoader.loadAsynchronously(m_worker->scriptExecutionContext(), m_url, DenyCrossOriginRequests, this); + // Keep the worker + JS wrapper alive until the resource load is complete in case we need to dispatch an error event. + m_worker->setPendingActivity(m_worker.get()); + m_loading = true; + } } // Extracts a WebMessagePortChannel from a MessagePortChannel. @@ -128,12 +164,6 @@ void SharedWorkerScriptLoader::sendConnect() m_webWorker->connect(getWebPort(m_port.release()), this); } -void SharedWorkerScriptLoader::contextDestroyed() -{ - ActiveDOMObject::contextDestroyed(); - delete this; -} - void SharedWorkerScriptLoader::connected() { // Connect event has been sent, so free ourselves (this releases the SharedWorker so it can be freed as well if unreferenced). @@ -185,6 +215,10 @@ void SharedWorkerRepository::documentDetached(Document* document) WebSharedWorkerRepository* repo = WebKit::webKitClient()->sharedWorkerRepository(); if (repo) repo->documentDetached(getId(document)); + + // Stop the creation of any pending SharedWorkers for this context. + // FIXME: Need a way to invoke this for WorkerContexts as well when we support for nested workers. + SharedWorkerScriptLoader::stopAllLoadersForContext(document); } bool SharedWorkerRepository::hasSharedWorkers(Document* document) diff --git a/WebKit/chromium/src/ToolsAgent.h b/WebKit/chromium/src/ToolsAgent.h new file mode 100644 index 0000000..fd1fcb7 --- /dev/null +++ b/WebKit/chromium/src/ToolsAgent.h @@ -0,0 +1,69 @@ +/* + * 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 ToolsAgent_h +#define ToolsAgent_h + +#include "DevToolsRPC.h" + +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 */) \ + \ + /* Dispatches given function on the InjectedScript object */ \ + METHOD5(dispatchOnInjectedScript, int /* call_id */, \ + int /* injected_script_id */, String /* function_name */, \ + String /* json_args */, bool /* async */) + +DEFINE_RPC_CLASS(ToolsAgent, TOOLS_AGENT_STRUCT) + +#define TOOLS_AGENT_DELEGATE_STRUCT(METHOD0, METHOD1, METHOD2, METHOD3, METHOD4, METHOD5) \ + /* Updates focused node on the client. */ \ + METHOD1(frameNavigate, String /* url */) \ + \ + /* Response to the DispatchOn*. */ \ + METHOD3(didDispatchOn, int /* call_id */, String /* result */, String /* exception */) \ + \ + /* Sends InspectorFrontend message to be dispatched on client. */ \ + METHOD1(dispatchOnClient, String /* data */) + +DEFINE_RPC_CLASS(ToolsAgentDelegate, TOOLS_AGENT_DELEGATE_STRUCT) + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/WebDevToolsAgentImpl.cpp b/WebKit/chromium/src/WebDevToolsAgentImpl.cpp new file mode 100644 index 0000000..9d386f3 --- /dev/null +++ b/WebKit/chromium/src/WebDevToolsAgentImpl.cpp @@ -0,0 +1,566 @@ +/* + * 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 "WebDevToolsAgentImpl.h" + +#include "BoundObject.h" +#include "DebuggerAgentImpl.h" +#include "DebuggerAgentManager.h" +#include "Document.h" +#include "EventListener.h" +#include "InjectedScriptHost.h" +#include "InspectorBackend.h" +#include "InspectorController.h" +#include "InspectorFrontend.h" +#include "InspectorResource.h" +#include "Node.h" +#include "Page.h" +#include "PlatformString.h" +#include "ProfilerAgentImpl.h" +#include "ResourceError.h" +#include "ResourceRequest.h" +#include "ResourceResponse.h" +#include "ScriptObject.h" +#include "ScriptState.h" +#include "ScriptValue.h" +#include "V8Binding.h" +#include "V8Proxy.h" +#include "V8Utilities.h" +#include "WebDataSource.h" +#include "WebDevToolsAgentClient.h" +#include "WebDevToolsMessageData.h" +#include "WebFrameImpl.h" +#include "WebString.h" +#include "WebURL.h" +#include "WebURLError.h" +#include "WebURLRequest.h" +#include "WebURLResponse.h" +#include "WebViewImpl.h" +#include <wtf/Noncopyable.h> +#include <wtf/OwnPtr.h> + +using WebCore::Document; +using WebCore::DocumentLoader; +using WebCore::FrameLoader; +using WebCore::InjectedScriptHost; +using WebCore::InspectorBackend; +using WebCore::InspectorController; +using WebCore::InspectorFrontend; +using WebCore::InspectorResource; +using WebCore::Node; +using WebCore::Page; +using WebCore::ResourceError; +using WebCore::ResourceRequest; +using WebCore::ResourceResponse; +using WebCore::SafeAllocation; +using WebCore::ScriptObject; +using WebCore::ScriptState; +using WebCore::ScriptValue; +using WebCore::String; +using WebCore::V8ClassIndex; +using WebCore::V8DOMWrapper; +using WebCore::V8Proxy; + +namespace WebKit { + +namespace { + +void InspectorBackendWeakReferenceCallback(v8::Persistent<v8::Value> object, void* parameter) +{ + InspectorBackend* backend = static_cast<InspectorBackend*>(parameter); + backend->deref(); + object.Dispose(); +} + +void SetApuAgentEnabledInUtilityContext(v8::Handle<v8::Context> context, bool enabled) +{ + v8::HandleScope handleScope; + v8::Context::Scope contextScope(context); + v8::Handle<v8::Object> dispatcher = v8::Local<v8::Object>::Cast( + context->Global()->Get(v8::String::New("ApuAgentDispatcher"))); + if (dispatcher.IsEmpty()) + return; + dispatcher->Set(v8::String::New("enabled"), v8::Boolean::New(enabled)); +} + +// TODO(pfeldman): Make this public in WebDevToolsAgent API. +static const char kApuAgentFeatureName[] = "apu-agent"; + +// Keep these in sync with the ones in inject_dispatch.js. +static const char kTimelineFeatureName[] = "timeline-profiler"; +static const char kResourceTrackingFeatureName[] = "resource-tracking"; + +class IORPCDelegate : public DevToolsRPC::Delegate, public Noncopyable { +public: + IORPCDelegate() { } + virtual ~IORPCDelegate() { } + virtual void sendRpcMessage(const WebDevToolsMessageData& data) + { + WebDevToolsAgentClient::sendMessageToFrontendOnIOThread(data); + } +}; + +} // namespace + +WebDevToolsAgentImpl::WebDevToolsAgentImpl( + WebViewImpl* webViewImpl, + WebDevToolsAgentClient* client) + : m_hostId(client->hostIdentifier()) + , m_client(client) + , m_webViewImpl(webViewImpl) + , m_apuAgentEnabled(false) + , m_resourceTrackingWasEnabled(false) + , m_attached(false) +{ + m_debuggerAgentDelegateStub.set(new DebuggerAgentDelegateStub(this)); + m_toolsAgentDelegateStub.set(new ToolsAgentDelegateStub(this)); + m_apuAgentDelegateStub.set(new ApuAgentDelegateStub(this)); +} + +WebDevToolsAgentImpl::~WebDevToolsAgentImpl() +{ + DebuggerAgentManager::onWebViewClosed(m_webViewImpl); + disposeUtilityContext(); +} + +void WebDevToolsAgentImpl::disposeUtilityContext() +{ + if (!m_utilityContext.IsEmpty()) { + m_utilityContext.Dispose(); + m_utilityContext.Clear(); + } +} + +void WebDevToolsAgentImpl::unhideResourcesPanelIfNecessary() +{ + InspectorController* ic = m_webViewImpl->page()->inspectorController(); + ic->ensureResourceTrackingSettingsLoaded(); + String command = String::format("[\"setResourcesPanelEnabled\", %s]", + ic->resourceTrackingEnabled() ? "true" : "false"); + m_toolsAgentDelegateStub->dispatchOnClient(command); +} + +void WebDevToolsAgentImpl::attach() +{ + if (m_attached) + return; + m_debuggerAgentImpl.set( + new DebuggerAgentImpl(m_webViewImpl, + m_debuggerAgentDelegateStub.get(), + this)); + resetInspectorFrontendProxy(); + unhideResourcesPanelIfNecessary(); + // Allow controller to send messages to the frontend. + InspectorController* ic = inspectorController(); + + { // TODO(yurys): the source should have already been pushed by the frontend. + v8::HandleScope scope; + v8::Context::Scope contextScope(m_utilityContext); + v8::Handle<v8::Value> constructorValue = m_utilityContext->Global()->Get( + v8::String::New("injectedScriptConstructor")); + if (constructorValue->IsFunction()) { + String source = WebCore::toWebCoreString(constructorValue); + ic->injectedScriptHost()->setInjectedScriptSource("(" + source + ")"); + } + } + + ic->setWindowVisible(true, false); + m_attached = true; +} + +void WebDevToolsAgentImpl::detach() +{ + // Prevent controller from sending messages to the frontend. + InspectorController* ic = m_webViewImpl->page()->inspectorController(); + ic->hideHighlight(); + ic->close(); + disposeUtilityContext(); + m_debuggerAgentImpl.set(0); + m_attached = false; + m_apuAgentEnabled = false; +} + +void WebDevToolsAgentImpl::didNavigate() +{ + DebuggerAgentManager::onNavigate(); +} + +void WebDevToolsAgentImpl::didCommitProvisionalLoad(WebFrameImpl* webframe, bool isNewNavigation) +{ + if (!m_attached) + return; + WebDataSource* ds = webframe->dataSource(); + const WebURLRequest& request = ds->request(); + WebURL url = ds->hasUnreachableURL() ? + ds->unreachableURL() : + request.url(); + if (!webframe->parent()) { + resetInspectorFrontendProxy(); + m_toolsAgentDelegateStub->frameNavigate(WebCore::KURL(url).string()); + SetApuAgentEnabledInUtilityContext(m_utilityContext, m_apuAgentEnabled); + unhideResourcesPanelIfNecessary(); + } +} + +void WebDevToolsAgentImpl::didClearWindowObject(WebFrameImpl* webframe) +{ + DebuggerAgentManager::setHostId(webframe, m_hostId); + if (m_attached) { + // Push context id into the client if it is already attached. + m_debuggerAgentDelegateStub->setContextId(m_hostId); + } +} + +void WebDevToolsAgentImpl::forceRepaint() +{ + m_client->forceRepaint(); +} + +void WebDevToolsAgentImpl::dispatchOnInspectorController(int callId, const String& functionName, const String& jsonArgs) +{ + String result; + String exception; + result = m_debuggerAgentImpl->executeUtilityFunction(m_utilityContext, callId, + "InspectorControllerDispatcher", functionName, jsonArgs, false /* is sync */, &exception); + m_toolsAgentDelegateStub->didDispatchOn(callId, result, exception); +} + +void WebDevToolsAgentImpl::dispatchOnInjectedScript(int callId, int injectedScriptId, const String& functionName, const String& jsonArgs, bool async) +{ + inspectorController()->inspectorBackend()->dispatchOnInjectedScript( + callId, + injectedScriptId, + functionName, + jsonArgs, + async); +} + +void WebDevToolsAgentImpl::executeVoidJavaScript() +{ + m_debuggerAgentImpl->executeVoidJavaScript(m_utilityContext); +} + +void WebDevToolsAgentImpl::dispatchMessageFromFrontend(const WebDevToolsMessageData& data) +{ + if (ToolsAgentDispatch::dispatch(this, data)) + return; + + if (!m_attached) + return; + + if (m_debuggerAgentImpl.get() && DebuggerAgentDispatch::dispatch(m_debuggerAgentImpl.get(), data)) + return; +} + +void WebDevToolsAgentImpl::inspectElementAt(const WebPoint& point) +{ + m_webViewImpl->inspectElementAt(point); +} + +void WebDevToolsAgentImpl::setRuntimeFeatureEnabled(const WebString& feature, bool enabled) +{ + if (feature == kApuAgentFeatureName) + setApuAgentEnabled(enabled); + else if (feature == kTimelineFeatureName) + setTimelineProfilingEnabled(enabled); + else if (feature == kResourceTrackingFeatureName) { + InspectorController* ic = m_webViewImpl->page()->inspectorController(); + if (enabled) + ic->enableResourceTracking(false /* not sticky */, false /* no reload */); + else + ic->disableResourceTracking(false /* not sticky */); + } +} + +void WebDevToolsAgentImpl::sendRpcMessage(const WebDevToolsMessageData& data) +{ + m_client->sendMessageToFrontend(data); +} + +void WebDevToolsAgentImpl::compileUtilityScripts() +{ + v8::HandleScope handleScope; + v8::Context::Scope contextScope(m_utilityContext); + // Inject javascript into the context. + WebCString injectedScriptJs = m_client->injectedScriptSource(); + v8::Script::Compile(v8::String::New( + injectedScriptJs.data(), + injectedScriptJs.length()))->Run(); + WebCString injectDispatchJs = m_client->injectedScriptDispatcherSource(); + v8::Script::Compile(v8::String::New( + injectDispatchJs.data(), + injectDispatchJs.length()))->Run(); +} + +void WebDevToolsAgentImpl::initDevToolsAgentHost() +{ + BoundObject devtoolsAgentHost(m_utilityContext, this, "DevToolsAgentHost"); + devtoolsAgentHost.addProtoFunction( + "dispatch", + WebDevToolsAgentImpl::jsDispatchOnClient); + devtoolsAgentHost.addProtoFunction( + "dispatchToApu", + WebDevToolsAgentImpl::jsDispatchToApu); + devtoolsAgentHost.addProtoFunction( + "evaluateOnSelf", + WebDevToolsAgentImpl::jsEvaluateOnSelf); + devtoolsAgentHost.addProtoFunction( + "runtimeFeatureStateChanged", + WebDevToolsAgentImpl::jsOnRuntimeFeatureStateChanged); + devtoolsAgentHost.build(); + + v8::HandleScope scope; + v8::Context::Scope utilityScope(m_utilityContext); + // Call custom code to create inspector backend wrapper in the utility context + // instead of calling V8DOMWrapper::convertToV8Object that would create the + // wrapper in the Page main frame context. + v8::Handle<v8::Object> backendWrapper = createInspectorBackendV8Wrapper(); + if (backendWrapper.IsEmpty()) + return; + m_utilityContext->Global()->Set(v8::String::New("InspectorBackend"), backendWrapper); +} + +v8::Local<v8::Object> WebDevToolsAgentImpl::createInspectorBackendV8Wrapper() +{ + V8ClassIndex::V8WrapperType descriptorType = V8ClassIndex::INSPECTORBACKEND; + v8::Handle<v8::Function> function = V8DOMWrapper::getTemplate(descriptorType)->GetFunction(); + if (function.IsEmpty()) { + // Return if allocation failed. + return v8::Local<v8::Object>(); + } + v8::Local<v8::Object> instance = SafeAllocation::newInstance(function); + if (instance.IsEmpty()) { + // Avoid setting the wrapper if allocation failed. + return v8::Local<v8::Object>(); + } + InspectorBackend* backend = m_webViewImpl->page()->inspectorController()->inspectorBackend(); + V8DOMWrapper::setDOMWrapper(instance, V8ClassIndex::ToInt(descriptorType), backend); + // Create a weak reference to the v8 wrapper of InspectorBackend to deref + // InspectorBackend when the wrapper is garbage collected. + backend->ref(); + v8::Persistent<v8::Object> weakHandle = v8::Persistent<v8::Object>::New(instance); + weakHandle.MakeWeak(backend, &InspectorBackendWeakReferenceCallback); + return instance; +} + +void WebDevToolsAgentImpl::resetInspectorFrontendProxy() +{ + disposeUtilityContext(); + m_debuggerAgentImpl->createUtilityContext(m_webViewImpl->page()->mainFrame(), &m_utilityContext); + compileUtilityScripts(); + initDevToolsAgentHost(); + + v8::HandleScope scope; + v8::Context::Scope contextScope(m_utilityContext); + ScriptState* state = ScriptState::forContext( + v8::Local<v8::Context>::New(m_utilityContext)); + InspectorController* ic = inspectorController(); + ic->setFrontendProxyObject(state, ScriptObject(state, m_utilityContext->Global())); +} + +void WebDevToolsAgentImpl::setApuAgentEnabled(bool enabled) +{ + m_apuAgentEnabled = enabled; + SetApuAgentEnabledInUtilityContext(m_utilityContext, enabled); + InspectorController* ic = m_webViewImpl->page()->inspectorController(); + if (enabled) { + m_resourceTrackingWasEnabled = ic->resourceTrackingEnabled(); + ic->startTimelineProfiler(); + if (!m_resourceTrackingWasEnabled) { + // TODO(knorton): Introduce some kind of agents dependency here so that + // user could turn off resource tracking while apu agent is on. + ic->enableResourceTracking(false, false); + } + m_debuggerAgentImpl->setAutoContinueOnException(true); + } else { + ic->stopTimelineProfiler(); + if (!m_resourceTrackingWasEnabled) + ic->disableResourceTracking(false); + m_resourceTrackingWasEnabled = false; + } + m_client->runtimeFeatureStateChanged( + kApuAgentFeatureName, + enabled); +} + +// static +v8::Handle<v8::Value> WebDevToolsAgentImpl::jsDispatchOnClient(const v8::Arguments& args) +{ + v8::TryCatch exceptionCatcher; + String message = WebCore::toWebCoreStringWithNullCheck(args[0]); + if (message.isEmpty() || exceptionCatcher.HasCaught()) + return v8::Undefined(); + WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>(v8::External::Cast(*args.Data())->Value()); + agent->m_toolsAgentDelegateStub->dispatchOnClient(message); + return v8::Undefined(); +} + +// static +v8::Handle<v8::Value> WebDevToolsAgentImpl::jsDispatchToApu(const v8::Arguments& args) +{ + v8::TryCatch exceptionCatcher; + String message = WebCore::toWebCoreStringWithNullCheck(args[0]); + if (message.isEmpty() || exceptionCatcher.HasCaught()) + return v8::Undefined(); + WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>( + v8::External::Cast(*args.Data())->Value()); + agent->m_apuAgentDelegateStub->dispatchToApu(message); + return v8::Undefined(); +} + +// static +v8::Handle<v8::Value> WebDevToolsAgentImpl::jsEvaluateOnSelf(const v8::Arguments& args) +{ + String code; + { + v8::TryCatch exceptionCatcher; + code = WebCore::toWebCoreStringWithNullCheck(args[0]); + if (code.isEmpty() || exceptionCatcher.HasCaught()) + return v8::Undefined(); + } + WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>(v8::External::Cast(*args.Data())->Value()); + v8::Context::Scope(agent->m_utilityContext); + V8Proxy* proxy = V8Proxy::retrieve(agent->m_webViewImpl->page()->mainFrame()); + v8::Local<v8::Value> result = proxy->runScript(v8::Script::Compile(v8::String::New(code.utf8().data())), true); + return result; +} + +// static +v8::Handle<v8::Value> WebDevToolsAgentImpl::jsOnRuntimeFeatureStateChanged(const v8::Arguments& args) +{ + v8::TryCatch exceptionCatcher; + String feature = WebCore::toWebCoreStringWithNullCheck(args[0]); + bool enabled = args[1]->ToBoolean()->Value(); + if (feature.isEmpty() || exceptionCatcher.HasCaught()) + return v8::Undefined(); + WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>(v8::External::Cast(*args.Data())->Value()); + agent->m_client->runtimeFeatureStateChanged(feature, enabled); + return v8::Undefined(); +} + + +WebCore::InspectorController* WebDevToolsAgentImpl::inspectorController() +{ + if (Page* page = m_webViewImpl->page()) + return page->inspectorController(); + return 0; +} + + +//------- plugin resource load notifications --------------- +void WebDevToolsAgentImpl::identifierForInitialRequest( + unsigned long resourceId, + WebFrame* frame, + const WebURLRequest& request) +{ + if (InspectorController* ic = inspectorController()) { + WebFrameImpl* webFrameImpl = static_cast<WebFrameImpl*>(frame); + FrameLoader* frameLoader = webFrameImpl->frame()->loader(); + DocumentLoader* loader = frameLoader->activeDocumentLoader(); + ic->identifierForInitialRequest(resourceId, loader, request.toResourceRequest()); + } +} + +void WebDevToolsAgentImpl::willSendRequest(unsigned long resourceId, const WebURLRequest& request) +{ + if (InspectorController* ic = inspectorController()) + ic->willSendRequest(resourceId, request.toResourceRequest(), ResourceResponse()); +} + +void WebDevToolsAgentImpl::didReceiveData(unsigned long resourceId, int length) +{ + if (InspectorController* ic = inspectorController()) + ic->didReceiveContentLength(resourceId, length); +} + +void WebDevToolsAgentImpl::didReceiveResponse(unsigned long resourceId, const WebURLResponse& response) +{ + if (InspectorController* ic = inspectorController()) + ic->didReceiveResponse(resourceId, response.toResourceResponse()); +} + +void WebDevToolsAgentImpl::didFinishLoading(unsigned long resourceId) +{ + if (InspectorController* ic = inspectorController()) + ic->didFinishLoading(resourceId); +} + +void WebDevToolsAgentImpl::didFailLoading(unsigned long resourceId, const WebURLError& error) +{ + ResourceError resourceError; + if (InspectorController* ic = inspectorController()) + ic->didFailLoading(resourceId, resourceError); +} + +void WebDevToolsAgentImpl::evaluateInWebInspector(long callId, const WebString& script) +{ + InspectorController* ic = inspectorController(); + ic->evaluateForTestInFrontend(callId, script); +} + +void WebDevToolsAgentImpl::setTimelineProfilingEnabled(bool enabled) +{ + InspectorController* ic = inspectorController(); + if (enabled) + ic->startTimelineProfiler(); + else + ic->stopTimelineProfiler(); +} + +WebDevToolsAgent* WebDevToolsAgent::create(WebView* webview, WebDevToolsAgentClient* client) +{ + return new WebDevToolsAgentImpl(static_cast<WebViewImpl*>(webview), client); +} + +void WebDevToolsAgent::executeDebuggerCommand(const WebString& command, int callerId) +{ + DebuggerAgentManager::executeDebuggerCommand(command, callerId); +} + +void WebDevToolsAgent::debuggerPauseScript() +{ + DebuggerAgentManager::pauseScript(); +} + +void WebDevToolsAgent::setMessageLoopDispatchHandler(MessageLoopDispatchHandler handler) +{ + DebuggerAgentManager::setMessageLoopDispatchHandler(handler); +} + +bool WebDevToolsAgent::dispatchMessageFromFrontendOnIOThread(const WebDevToolsMessageData& data) +{ + IORPCDelegate transport; + ProfilerAgentDelegateStub stub(&transport); + ProfilerAgentImpl agent(&stub); + return ProfilerAgentDispatch::dispatch(&agent, data); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebDevToolsAgentImpl.h b/WebKit/chromium/src/WebDevToolsAgentImpl.h new file mode 100644 index 0000000..3f5928b --- /dev/null +++ b/WebKit/chromium/src/WebDevToolsAgentImpl.h @@ -0,0 +1,142 @@ +/* + * 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 WebDevToolsAgentImpl_h +#define WebDevToolsAgentImpl_h + +#include "APUAgentDelegate.h" +#include "DevToolsRPC.h" +#include "ToolsAgent.h" +#include "WebDevToolsAgentPrivate.h" + +#include <v8.h> +#include <wtf/OwnPtr.h> + +namespace WebCore { +class Document; +class InspectorController; +class Node; +class String; +} + +namespace WebKit { + +class DebuggerAgentDelegateStub; +class DebuggerAgentImpl; +class WebDevToolsAgentClient; +class WebFrame; +class WebFrameImpl; +class WebString; +class WebURLRequest; +class WebURLResponse; +class WebViewImpl; +struct WebURLError; +struct WebDevToolsMessageData; + +class WebDevToolsAgentImpl : public WebDevToolsAgentPrivate, + public ToolsAgent, + public DevToolsRPC::Delegate { +public: + WebDevToolsAgentImpl(WebViewImpl* webViewImpl, WebDevToolsAgentClient* client); + virtual ~WebDevToolsAgentImpl(); + + // 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); + virtual void didCommitProvisionalLoad(WebFrameImpl* frame, bool isNewNavigation); + + // WebDevToolsAgent implementation. + virtual void attach(); + virtual void detach(); + virtual void didNavigate(); + virtual void dispatchMessageFromFrontend(const WebDevToolsMessageData& data); + virtual void inspectElementAt(const WebPoint& point); + virtual void evaluateInWebInspector(long callId, const WebString& script); + virtual void setRuntimeFeatureEnabled(const WebString& feature, bool enabled); + virtual void setTimelineProfilingEnabled(bool enable); + + virtual void identifierForInitialRequest(unsigned long, WebFrame*, const WebURLRequest&); + virtual void willSendRequest(unsigned long, const WebURLRequest&); + virtual void didReceiveData(unsigned long, int length); + virtual void didReceiveResponse(unsigned long, const WebURLResponse&); + virtual void didFinishLoading(unsigned long); + virtual void didFailLoading(unsigned long, const WebURLError&); + + // DevToolsRPC::Delegate implementation. + virtual void sendRpcMessage(const WebDevToolsMessageData& data); + + void forceRepaint(); + + int hostId() { return m_hostId; } + +private: + static v8::Handle<v8::Value> jsDispatchOnClient(const v8::Arguments& args); + static v8::Handle<v8::Value> jsDispatchToApu(const v8::Arguments& args); + static v8::Handle<v8::Value> jsEvaluateOnSelf(const v8::Arguments& args); + static v8::Handle<v8::Value> jsOnRuntimeFeatureStateChanged(const v8::Arguments& args); + + void disposeUtilityContext(); + void unhideResourcesPanelIfNecessary(); + + void compileUtilityScripts(); + void initDevToolsAgentHost(); + void resetInspectorFrontendProxy(); + void setApuAgentEnabled(bool enabled); + + WebCore::InspectorController* inspectorController(); + + // Creates InspectorBackend v8 wrapper in the utility context so that it's + // methods prototype is Function.protoype object from the utility context. + // Otherwise some useful methods defined on Function.prototype(such as bind) + // are missing for InspectorController native methods. + v8::Local<v8::Object> createInspectorBackendV8Wrapper(); + + int m_hostId; + WebDevToolsAgentClient* m_client; + WebViewImpl* m_webViewImpl; + OwnPtr<DebuggerAgentDelegateStub> m_debuggerAgentDelegateStub; + OwnPtr<ToolsAgentDelegateStub> m_toolsAgentDelegateStub; + OwnPtr<DebuggerAgentImpl> m_debuggerAgentImpl; + OwnPtr<ApuAgentDelegateStub> m_apuAgentDelegateStub; + bool m_apuAgentEnabled; + bool m_resourceTrackingWasEnabled; + bool m_attached; + // TODO(pfeldman): This should not be needed once GC styles issue is fixed + // for matching rules. + v8::Persistent<v8::Context> m_utilityContext; +}; + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp b/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp new file mode 100644 index 0000000..0a92319 --- /dev/null +++ b/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp @@ -0,0 +1,396 @@ +/* + * 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 "WebDevToolsFrontendImpl.h" + +#include "BoundObject.h" +#include "ContextMenuController.h" +#include "ContextMenuItem.h" +#include "DOMWindow.h" +#include "DebuggerAgent.h" +#include "DevToolsRPCJS.h" +#include "Document.h" +#include "Event.h" +#include "Frame.h" +#include "InspectorBackend.h" +#include "InspectorController.h" +#include "InspectorFrontendHost.h" +#include "Node.h" +#include "Page.h" +#include "Pasteboard.h" +#include "PlatformString.h" +#include "ProfilerAgent.h" +#include "SecurityOrigin.h" +#include "Settings.h" +#include "ToolsAgent.h" +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8DOMWrapper.h" +#include "V8InspectorFrontendHost.h" +#include "V8Node.h" +#include "V8Proxy.h" +#include "V8Utilities.h" +#include "WebDevToolsFrontendClient.h" +#include "WebFrameImpl.h" +#include "WebScriptSource.h" +#include "WebViewImpl.h" +#include <wtf/OwnPtr.h> +#include <wtf/Vector.h> + +using namespace WebCore; + +namespace WebKit { + +static v8::Local<v8::String> ToV8String(const String& s) +{ + if (s.isNull()) + return v8::Local<v8::String>(); + + return v8::String::New(reinterpret_cast<const uint16_t*>(s.characters()), s.length()); +} + +DEFINE_RPC_JS_BOUND_OBJ(DebuggerAgent, DEBUGGER_AGENT_STRUCT, DebuggerAgentDelegate, DEBUGGER_AGENT_DELEGATE_STRUCT) +DEFINE_RPC_JS_BOUND_OBJ(ProfilerAgent, PROFILER_AGENT_STRUCT, ProfilerAgentDelegate, PROFILER_AGENT_DELEGATE_STRUCT) +DEFINE_RPC_JS_BOUND_OBJ(ToolsAgent, TOOLS_AGENT_STRUCT, ToolsAgentDelegate, TOOLS_AGENT_DELEGATE_STRUCT) + +WebDevToolsFrontend* WebDevToolsFrontend::create( + WebView* view, + WebDevToolsFrontendClient* client, + const WebString& applicationLocale) +{ + return new WebDevToolsFrontendImpl( + static_cast<WebViewImpl*>(view), + client, + applicationLocale); +} + +WebDevToolsFrontendImpl::WebDevToolsFrontendImpl( + WebViewImpl* webViewImpl, + WebDevToolsFrontendClient* client, + const String& applicationLocale) + : m_webViewImpl(webViewImpl) + , m_client(client) + , m_applicationLocale(applicationLocale) + , m_loaded(false) +{ + WebFrameImpl* frame = m_webViewImpl->mainFrameImpl(); + v8::HandleScope scope; + v8::Handle<v8::Context> frameContext = V8Proxy::context(frame->frame()); + + m_debuggerAgentObj.set(new JSDebuggerAgentBoundObj(this, frameContext, "RemoteDebuggerAgent")); + m_profilerAgentObj.set(new JSProfilerAgentBoundObj(this, frameContext, "RemoteProfilerAgent")); + m_toolsAgentObj.set(new JSToolsAgentBoundObj(this, frameContext, "RemoteToolsAgent")); + + // Debugger commands should be sent using special method. + BoundObject debuggerCommandExecutorObj(frameContext, this, "RemoteDebuggerCommandExecutor"); + debuggerCommandExecutorObj.addProtoFunction( + "DebuggerCommand", + WebDevToolsFrontendImpl::jsDebuggerCommand); + debuggerCommandExecutorObj.addProtoFunction( + "DebuggerPauseScript", + WebDevToolsFrontendImpl::jsDebuggerPauseScript); + debuggerCommandExecutorObj.build(); + + BoundObject devToolsHost(frameContext, this, "InspectorFrontendHost"); + devToolsHost.addProtoFunction( + "loaded", + WebDevToolsFrontendImpl::jsLoaded); + devToolsHost.addProtoFunction( + "platform", + WebDevToolsFrontendImpl::jsPlatform); + devToolsHost.addProtoFunction( + "port", + WebDevToolsFrontendImpl::jsPort); + devToolsHost.addProtoFunction( + "copyText", + WebDevToolsFrontendImpl::jsCopyText); + devToolsHost.addProtoFunction( + "activateWindow", + WebDevToolsFrontendImpl::jsActivateWindow); + devToolsHost.addProtoFunction( + "closeWindow", + WebDevToolsFrontendImpl::jsCloseWindow); + devToolsHost.addProtoFunction( + "attach", + WebDevToolsFrontendImpl::jsDockWindow); + devToolsHost.addProtoFunction( + "detach", + WebDevToolsFrontendImpl::jsUndockWindow); + devToolsHost.addProtoFunction( + "localizedStringsURL", + WebDevToolsFrontendImpl::jsLocalizedStringsURL); + devToolsHost.addProtoFunction( + "hiddenPanels", + WebDevToolsFrontendImpl::jsHiddenPanels); + devToolsHost.addProtoFunction( + "setting", + WebDevToolsFrontendImpl::jsSetting); + devToolsHost.addProtoFunction( + "setSetting", + WebDevToolsFrontendImpl::jsSetSetting); + devToolsHost.addProtoFunction( + "windowUnloading", + WebDevToolsFrontendImpl::jsWindowUnloading); + devToolsHost.addProtoFunction( + "showContextMenu", + WebDevToolsFrontendImpl::jsShowContextMenu); + devToolsHost.build(); +} + +WebDevToolsFrontendImpl::~WebDevToolsFrontendImpl() +{ + if (m_menuProvider) + m_menuProvider->disconnect(); +} + +void WebDevToolsFrontendImpl::dispatchMessageFromAgent(const WebDevToolsMessageData& data) +{ + Vector<String> v; + v.append(data.className); + v.append(data.methodName); + for (size_t i = 0; i < data.arguments.size(); i++) + v.append(data.arguments[i]); + if (!m_loaded) { + m_pendingIncomingMessages.append(v); + return; + } + executeScript(v); +} + +void WebDevToolsFrontendImpl::executeScript(const Vector<String>& v) +{ + WebFrameImpl* frame = m_webViewImpl->mainFrameImpl(); + v8::HandleScope scope; + v8::Handle<v8::Context> frameContext = V8Proxy::context(frame->frame()); + v8::Context::Scope contextScope(frameContext); + v8::Handle<v8::Value> dispatchFunction = frameContext->Global()->Get(v8::String::New("devtools$$dispatch")); + ASSERT(dispatchFunction->IsFunction()); + v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(dispatchFunction); + Vector< v8::Handle<v8::Value> > args; + for (size_t i = 0; i < v.size(); i++) + args.append(ToV8String(v.at(i))); + function->Call(frameContext->Global(), args.size(), args.data()); +} + +void WebDevToolsFrontendImpl::dispatchOnWebInspector(const String& methodName, const String& param) +{ + WebFrameImpl* frame = m_webViewImpl->mainFrameImpl(); + v8::HandleScope scope; + v8::Handle<v8::Context> frameContext = V8Proxy::context(frame->frame()); + v8::Context::Scope contextScope(frameContext); + + v8::Handle<v8::Value> webInspector = frameContext->Global()->Get(v8::String::New("WebInspector")); + ASSERT(webInspector->IsObject()); + v8::Handle<v8::Object> webInspectorObj = v8::Handle<v8::Object>::Cast(webInspector); + + v8::Handle<v8::Value> method = webInspectorObj->Get(ToV8String(methodName)); + ASSERT(method->IsFunction()); + v8::Handle<v8::Function> methodFunc = v8::Handle<v8::Function>::Cast(method); + v8::Handle<v8::Value> args[] = { + ToV8String(param) + }; + methodFunc->Call(frameContext->Global(), 1, args); +} + +void WebDevToolsFrontendImpl::sendRpcMessage(const WebDevToolsMessageData& data) +{ + m_client->sendMessageToAgent(data); +} + +void WebDevToolsFrontendImpl::contextMenuItemSelected(ContextMenuItem* item) +{ + int itemNumber = item->action() - ContextMenuItemBaseCustomTag; + dispatchOnWebInspector("contextMenuItemSelected", String::number(itemNumber)); +} + +void WebDevToolsFrontendImpl::contextMenuCleared() +{ + dispatchOnWebInspector("contextMenuCleared", ""); +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsLoaded(const v8::Arguments& args) +{ + WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); + frontend->m_loaded = true; + + // Grant the devtools page the ability to have source view iframes. + Page* page = V8Proxy::retrieveFrameForEnteredContext()->page(); + SecurityOrigin* origin = page->mainFrame()->domWindow()->securityOrigin(); + origin->grantUniversalAccess(); + + for (Vector<Vector<String> >::iterator it = frontend->m_pendingIncomingMessages.begin(); + it != frontend->m_pendingIncomingMessages.end(); + ++it) { + frontend->executeScript(*it); + } + frontend->m_pendingIncomingMessages.clear(); + return v8::Undefined(); +} + +// static +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsPlatform(const v8::Arguments& args) +{ +#if defined(OS_MACOSX) + return v8String("mac"); +#elif defined(OS_LINUX) + return v8String("linux"); +#elif defined(OS_WIN) + return v8String("windows"); +#else + return v8String("unknown"); +#endif +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsPort(const v8::Arguments& args) +{ + return v8::Undefined(); +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsCopyText(const v8::Arguments& args) +{ + String text = WebCore::toWebCoreStringWithNullCheck(args[0]); + Pasteboard::generalPasteboard()->writePlainText(text); + return v8::Undefined(); +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsActivateWindow(const v8::Arguments& args) +{ + WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); + frontend->m_client->activateWindow(); + return v8::Undefined(); +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsCloseWindow(const v8::Arguments& args) +{ + WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); + frontend->m_client->closeWindow(); + return v8::Undefined(); +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsDockWindow(const v8::Arguments& args) +{ + WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); + frontend->m_client->dockWindow(); + return v8::Undefined(); +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsUndockWindow(const v8::Arguments& args) +{ + WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); + frontend->m_client->undockWindow(); + return v8::Undefined(); +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsLocalizedStringsURL(const v8::Arguments& args) +{ + return v8::Undefined(); +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsHiddenPanels(const v8::Arguments& args) +{ + return v8String(""); +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsDebuggerCommand(const v8::Arguments& args) +{ + WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); + WebString command = WebCore::toWebCoreStringWithNullCheck(args[0]); + frontend->m_client->sendDebuggerCommandToAgent(command); + return v8::Undefined(); +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsSetting(const v8::Arguments& args) +{ + return v8::Undefined(); +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsSetSetting(const v8::Arguments& args) +{ + return v8::Undefined(); +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsDebuggerPauseScript(const v8::Arguments& args) +{ + WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); + frontend->m_client->sendDebuggerPauseScript(); + return v8::Undefined(); +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsWindowUnloading(const v8::Arguments& args) +{ + // TODO(pfeldman): Implement this. + return v8::Undefined(); +} + +v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsShowContextMenu(const v8::Arguments& args) +{ + if (args.Length() < 2) + return v8::Undefined(); + + v8::Local<v8::Object> eventWrapper = v8::Local<v8::Object>::Cast(args[0]); + if (V8DOMWrapper::domWrapperType(eventWrapper) != V8ClassIndex::EVENT) + return v8::Undefined(); + + Event* event = V8Event::toNative(eventWrapper); + if (!args[1]->IsArray()) + return v8::Undefined(); + + v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(args[1]); + Vector<ContextMenuItem*> items; + + for (size_t i = 0; i < array->Length(); ++i) { + v8::Local<v8::Object> item = v8::Local<v8::Object>::Cast(array->Get(v8::Integer::New(i))); + v8::Local<v8::Value> label = item->Get(v8::String::New("label")); + v8::Local<v8::Value> id = item->Get(v8::String::New("id")); + if (label->IsUndefined() || id->IsUndefined()) { + items.append(new ContextMenuItem(SeparatorType, + ContextMenuItemTagNoAction, + String())); + } else { + ContextMenuAction typedId = static_cast<ContextMenuAction>( + ContextMenuItemBaseCustomTag + id->ToInt32()->Value()); + items.append(new ContextMenuItem(ActionType, + typedId, + toWebCoreStringWithNullCheck(label))); + } + } + + WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); + + frontend->m_menuProvider = MenuProvider::create(frontend, items); + + ContextMenuController* menuController = frontend->m_webViewImpl->page()->contextMenuController(); + menuController->showContextMenu(event, frontend->m_menuProvider); + + return v8::Undefined(); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebDevToolsFrontendImpl.h b/WebKit/chromium/src/WebDevToolsFrontendImpl.h new file mode 100644 index 0000000..62b34da --- /dev/null +++ b/WebKit/chromium/src/WebDevToolsFrontendImpl.h @@ -0,0 +1,161 @@ +/* + * 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 WebDevToolsFrontendImpl_h +#define WebDevToolsFrontendImpl_h + +#include "ContextMenu.h" +#include "ContextMenuProvider.h" +#include "DevToolsRPC.h" +#include "WebDevToolsFrontend.h" +#include <v8.h> +#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> +#include <wtf/OwnPtr.h> +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { +class ContextMenuItem; +class Node; +class Page; +class String; +} + +namespace WebKit { + +class JSDebuggerAgentBoundObj; +class JSProfilerAgentBoundObj; +class JSToolsAgentBoundObj; +class WebDevToolsClientDelegate; +class WebViewImpl; +struct WebDevToolsMessageData; + +class WebDevToolsFrontendImpl : public WebKit::WebDevToolsFrontend + , public DevToolsRPC::Delegate + , public Noncopyable { +public: + WebDevToolsFrontendImpl( + WebKit::WebViewImpl* webViewImpl, + WebKit::WebDevToolsFrontendClient* client, + const String& applicationLocale); + virtual ~WebDevToolsFrontendImpl(); + + // DevToolsRPC::Delegate implementation. + virtual void sendRpcMessage(const WebKit::WebDevToolsMessageData& data); + + // WebDevToolsFrontend implementation. + virtual void dispatchMessageFromAgent(const WebKit::WebDevToolsMessageData& data); + +private: + class MenuProvider : public WebCore::ContextMenuProvider { + public: + static PassRefPtr<MenuProvider> create(WebDevToolsFrontendImpl* frontendHost, const Vector<WebCore::ContextMenuItem*>& items) + { + return adoptRef(new MenuProvider(frontendHost, items)); + } + + virtual ~MenuProvider() + { + contextMenuCleared(); + } + + void disconnect() + { + m_frontendHost = 0; + } + + virtual void populateContextMenu(WebCore::ContextMenu* menu) + { + for (size_t i = 0; i < m_items.size(); ++i) + menu->appendItem(*m_items[i]); + } + + virtual void contextMenuItemSelected(WebCore::ContextMenuItem* item) + { + if (m_frontendHost) + m_frontendHost->contextMenuItemSelected(item); + } + + virtual void contextMenuCleared() + { + if (m_frontendHost) + m_frontendHost->contextMenuCleared(); + deleteAllValues(m_items); + m_items.clear(); + } + + private: + MenuProvider(WebDevToolsFrontendImpl* frontendHost, const Vector<WebCore::ContextMenuItem*>& items) + : m_frontendHost(frontendHost) + , m_items(items) { } + WebDevToolsFrontendImpl* m_frontendHost; + Vector<WebCore::ContextMenuItem*> m_items; + }; + + void executeScript(const Vector<String>& v); + void dispatchOnWebInspector(const String& method, const String& param); + + // friend class MenuSelectionHandler; + void contextMenuItemSelected(WebCore::ContextMenuItem* menuItem); + void contextMenuCleared(); + + static v8::Handle<v8::Value> jsLoaded(const v8::Arguments& args); + static v8::Handle<v8::Value> jsPlatform(const v8::Arguments& args); + static v8::Handle<v8::Value> jsPort(const v8::Arguments& args); + static v8::Handle<v8::Value> jsCopyText(const v8::Arguments& args); + + static v8::Handle<v8::Value> jsActivateWindow(const v8::Arguments& args); + static v8::Handle<v8::Value> jsCloseWindow(const v8::Arguments& args); + static v8::Handle<v8::Value> jsDockWindow(const v8::Arguments& args); + static v8::Handle<v8::Value> jsUndockWindow(const v8::Arguments& args); + static v8::Handle<v8::Value> jsLocalizedStringsURL(const v8::Arguments& args); + static v8::Handle<v8::Value> jsHiddenPanels(const v8::Arguments& args); + static v8::Handle<v8::Value> jsDebuggerCommand(const v8::Arguments& args); + static v8::Handle<v8::Value> jsSetting(const v8::Arguments& args); + static v8::Handle<v8::Value> jsSetSetting(const v8::Arguments& args); + static v8::Handle<v8::Value> jsDebuggerPauseScript(const v8::Arguments& args); + static v8::Handle<v8::Value> jsWindowUnloading(const v8::Arguments& args); + static v8::Handle<v8::Value> jsShowContextMenu(const v8::Arguments& args); + + WebKit::WebViewImpl* m_webViewImpl; + WebKit::WebDevToolsFrontendClient* m_client; + String m_applicationLocale; + OwnPtr<JSDebuggerAgentBoundObj> m_debuggerAgentObj; + OwnPtr<JSProfilerAgentBoundObj> m_profilerAgentObj; + OwnPtr<JSToolsAgentBoundObj> m_toolsAgentObj; + bool m_loaded; + Vector<Vector<String> > m_pendingIncomingMessages; + RefPtr<MenuProvider> m_menuProvider; +}; + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/WebFrameImpl.cpp b/WebKit/chromium/src/WebFrameImpl.cpp index 28c27cc..2f911f1 100644 --- a/WebKit/chromium/src/WebFrameImpl.cpp +++ b/WebKit/chromium/src/WebFrameImpl.cpp @@ -1077,6 +1077,28 @@ WebString WebFrameImpl::selectionAsMarkup() const return createMarkup(range.get(), 0); } +void WebFrameImpl::selectWordAroundPosition(Frame* frame, VisiblePosition pos) +{ + VisibleSelection selection(pos); + selection.expandUsingGranularity(WordGranularity); + + if (selection.isRange()) + frame->setSelectionGranularity(WordGranularity); + + if (frame->shouldChangeSelection(selection)) + frame->selection()->setSelection(selection); +} + +bool WebFrameImpl::selectWordAroundCaret() +{ + SelectionController* controller = frame()->selection(); + ASSERT(!controller->isNone()); + if (controller->isNone() || controller->isRange()) + return false; + selectWordAroundPosition(frame(), controller->selection().visibleStart()); + return true; +} + int WebFrameImpl::printBegin(const WebSize& pageSize) { ASSERT(!frame()->document()->isFrameSet()); @@ -1496,6 +1518,21 @@ WebString WebFrameImpl::counterValueForElementById(const WebString& id) const return counterValueForElement(element); } +int WebFrameImpl::pageNumberForElementById(const WebString& id, + float pageWidthInPixels, + float pageHeightInPixels) const +{ + if (!m_frame) + return -1; + + Element* element = m_frame->document()->getElementById(id); + if (!element) + return -1; + + FloatSize pageSize(pageWidthInPixels, pageHeightInPixels); + return PrintContext::pageNumberForElement(element, pageSize); +} + // WebFrameImpl public --------------------------------------------------------- PassRefPtr<WebFrameImpl> WebFrameImpl::create(WebFrameClient* client) diff --git a/WebKit/chromium/src/WebFrameImpl.h b/WebKit/chromium/src/WebFrameImpl.h index ba8d279..ccba6d4 100644 --- a/WebKit/chromium/src/WebFrameImpl.h +++ b/WebKit/chromium/src/WebFrameImpl.h @@ -141,6 +141,7 @@ public: virtual WebRange selectionRange() const; virtual WebString selectionAsText() const; virtual WebString selectionAsMarkup() const; + virtual bool selectWordAroundCaret(); virtual int printBegin(const WebSize& pageSize); virtual float printPage(int pageToPrint, WebCanvas*); virtual float getPrintPageShrink(int page); @@ -163,6 +164,9 @@ public: virtual WebString contentAsMarkup() const; virtual WebString renderTreeAsText() const; virtual WebString counterValueForElementById(const WebString& id) const; + virtual int pageNumberForElementById(const WebString& id, + float pageWidthInPixels, + float pageHeightInPixels) const; static PassRefPtr<WebFrameImpl> create(WebFrameClient* client); ~WebFrameImpl(); @@ -219,6 +223,8 @@ public: WebFrameClient* client() const { return m_client; } void dropClient() { m_client = 0; } + static void selectWordAroundPosition(WebCore::Frame*, WebCore::VisiblePosition); + private: class DeferredScopeStringMatches; friend class DeferredScopeStringMatches; diff --git a/WebKit/chromium/src/WebMediaPlayerClientImpl.cpp b/WebKit/chromium/src/WebMediaPlayerClientImpl.cpp index c2a3535..b1f1f03 100644 --- a/WebKit/chromium/src/WebMediaPlayerClientImpl.cpp +++ b/WebKit/chromium/src/WebMediaPlayerClientImpl.cpp @@ -85,10 +85,16 @@ void WebMediaPlayerClientImpl::readyStateChanged() m_mediaPlayer->readyStateChanged(); } -void WebMediaPlayerClientImpl::volumeChanged() +void WebMediaPlayerClientImpl::volumeChanged(float newVolume) { ASSERT(m_mediaPlayer); - m_mediaPlayer->volumeChanged(); + m_mediaPlayer->volumeChanged(newVolume); +} + +void WebMediaPlayerClientImpl::muteChanged(bool newMute) +{ + ASSERT(m_mediaPlayer); + m_mediaPlayer->muteChanged(newMute); } void WebMediaPlayerClientImpl::timeChanged() diff --git a/WebKit/chromium/src/WebMediaPlayerClientImpl.h b/WebKit/chromium/src/WebMediaPlayerClientImpl.h index 7f087d0..4adbed2 100644 --- a/WebKit/chromium/src/WebMediaPlayerClientImpl.h +++ b/WebKit/chromium/src/WebMediaPlayerClientImpl.h @@ -53,7 +53,8 @@ public: // WebMediaPlayerClient methods: virtual void networkStateChanged(); virtual void readyStateChanged(); - virtual void volumeChanged(); + virtual void volumeChanged(float); + virtual void muteChanged(bool); virtual void timeChanged(); virtual void repaint(); virtual void durationChanged(); diff --git a/WebKit/chromium/src/WebSecurityOrigin.cpp b/WebKit/chromium/src/WebSecurityOrigin.cpp index 87916ca..81546da 100644 --- a/WebKit/chromium/src/WebSecurityOrigin.cpp +++ b/WebKit/chromium/src/WebSecurityOrigin.cpp @@ -47,6 +47,11 @@ WebSecurityOrigin* WebSecurityOrigin::createFromDatabaseIdentifier(const WebStri return new WebSecurityOrigin(SecurityOrigin::createFromDatabaseIdentifier(databaseIdentifier)); } +WebSecurityOrigin WebSecurityOrigin::createFromString(const WebString& origin) +{ + return WebSecurityOrigin(SecurityOrigin::createFromString(origin)); +} + void WebSecurityOrigin::reset() { assign(0); diff --git a/WebKit/chromium/src/WebViewImpl.cpp b/WebKit/chromium/src/WebViewImpl.cpp index 97825e9..e030d72 100644 --- a/WebKit/chromium/src/WebViewImpl.cpp +++ b/WebKit/chromium/src/WebViewImpl.cpp @@ -1316,9 +1316,9 @@ void WebViewImpl::performMediaPlayerAction(const WebMediaPlayerAction& action, switch (action.type) { case WebMediaPlayerAction::Play: if (action.enable) - mediaElement->play(); + mediaElement->play(mediaElement->processingUserGesture()); else - mediaElement->pause(); + mediaElement->pause(mediaElement->processingUserGesture()); break; case WebMediaPlayerAction::Mute: mediaElement->setMuted(action.enable); @@ -1694,6 +1694,20 @@ void WebViewImpl::setSelectionColors(unsigned activeBackgroundColor, #endif } +void WebViewImpl::addUserScript(const WebString& sourceCode, bool runAtStart) +{ + PageGroup* pageGroup = PageGroup::pageGroup(pageGroupName); + RefPtr<DOMWrapperWorld> world(DOMWrapperWorld::create()); + pageGroup->addUserScriptToWorld(world.get(), sourceCode, WebURL(), 0, 0, + runAtStart ? InjectAtDocumentStart : InjectAtDocumentEnd); +} + +void WebViewImpl::removeAllUserContent() +{ + PageGroup* pageGroup = PageGroup::pageGroup(pageGroupName); + pageGroup->removeAllUserContent(); +} + void WebViewImpl::didCommitLoad(bool* isNewNavigation) { if (isNewNavigation) diff --git a/WebKit/chromium/src/WebViewImpl.h b/WebKit/chromium/src/WebViewImpl.h index ed5cc5f..e2292f4 100644 --- a/WebKit/chromium/src/WebViewImpl.h +++ b/WebKit/chromium/src/WebViewImpl.h @@ -162,6 +162,9 @@ public: unsigned inactiveBackgroundColor, unsigned inactiveForegroundColor); virtual void performCustomContextMenuAction(unsigned action); + virtual void addUserScript(const WebString& sourceCode, + bool runAtStart); + virtual void removeAllUserContent(); // WebViewImpl diff --git a/WebKit/chromium/src/linux/WebRenderTheme.cpp b/WebKit/chromium/src/linux/WebRenderTheme.cpp new file mode 100644 index 0000000..16ea22c --- /dev/null +++ b/WebKit/chromium/src/linux/WebRenderTheme.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2010 Joel Stanley. 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 "WebRenderTheme.h" + +#include "RenderThemeChromiumLinux.h" +#include "WebView.h" + +using WebCore::RenderTheme; +using WebCore::RenderThemeChromiumLinux; + +namespace WebKit { + +void setCaretBlinkInterval(double interval) +{ + RenderThemeChromiumLinux::setCaretBlinkInterval(interval); +} + +} // namespace WebKit diff --git a/WebKit/gtk/ChangeLog b/WebKit/gtk/ChangeLog index 3cd90de..92de7e4 100644 --- a/WebKit/gtk/ChangeLog +++ b/WebKit/gtk/ChangeLog @@ -1,3 +1,29 @@ +2010-02-02 Gustavo Noronha Silva <gns@gnome.org> + + Reviewed by Xan Lopez. + + Changes in 1.1.20, and documentation control files update. + + * NEWS: + * docs/webkitgtk-docs.sgml: + +2010-02-02 Martin Robinson <martin.james.robinson@gmail.com> + + Reviewed by Gustavo Noronha Silva. + + [GTK] When selection changes selections in other WebView are not collapsed + https://bugs.webkit.org/show_bug.cgi?id=34043 + + Collapse the selection of a WebView even when the new selection owner is + a new WebView. + + * WebCoreSupport/PasteboardHelperGtk.cpp: + (WebKit::clearClipboardContentsCallback): Only clear the DataObject we are setting + is not the same as the one referenced in this callback. Use the same behavior for + collapsing the selection. + (WebKit::PasteboardHelperGtk::writeClipboardContents): Instead of recording a boolean + record the actual data used while writing to the clipboard. + 2010-01-27 Martin Robinson <mrobinson@webkit.org> Reviewed by Gustavo Noronha Silva. diff --git a/WebKit/gtk/NEWS b/WebKit/gtk/NEWS index 18b5e3c..807fca4 100644 --- a/WebKit/gtk/NEWS +++ b/WebKit/gtk/NEWS @@ -1,4 +1,18 @@ ================= +WebKitGTK+ 1.1.20 +================= + +What's new in WebKitGTK+ 1.1.20? + + - Fixes to the HTML5 Media Player infrastructure to satisfy sites + that require cookies, and Referer to be sent; this makes + WebKitGTK+ able to support the new HTML5 support added to Youtube, + and Vimeo, for instance. + - Windowless plugin support is finally here, making it possible to + get plugins to behave on various web pages. + - The usual stream of fixes, and improvements + +================= WebKitGTK+ 1.1.19 ================= diff --git a/WebKit/gtk/WebCoreSupport/PasteboardHelperGtk.cpp b/WebKit/gtk/WebCoreSupport/PasteboardHelperGtk.cpp index 8406ada..b8eb92d 100644 --- a/WebKit/gtk/WebCoreSupport/PasteboardHelperGtk.cpp +++ b/WebKit/gtk/WebCoreSupport/PasteboardHelperGtk.cpp @@ -105,7 +105,8 @@ static GtkTargetList* targetListForDataObject(DataObjectGtk* dataObject) return list; } -static bool settingClipboard = false; +static DataObjectGtk* settingClipboardDataObject = 0; +static gpointer settingClipboardData = 0; static void getClipboardContentsCallback(GtkClipboard* clipboard, GtkSelectionData *selectionData, guint info, gpointer data) { DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard); @@ -115,17 +116,16 @@ static void getClipboardContentsCallback(GtkClipboard* clipboard, GtkSelectionDa static void clearClipboardContentsCallback(GtkClipboard* clipboard, gpointer data) { - // GTK will call the clear clipboard callback while setting clipboard data. - // We don't actually want to clear the DataObject during that time. - if (settingClipboard) - return; - DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard); ASSERT(dataObject); - dataObject->clear(); - // This will be true for clipboards other than X11 primary. - if (!data) + // Only clear the DataObject for this clipboard if we are not currently setting it. + if (dataObject != settingClipboardDataObject) + dataObject->clear(); + + // Only collapse the selection if this is an X11 primary clipboard + // and we aren't currently setting the clipboard for this WebView. + if (!data || data == settingClipboardData) return; WebKitWebView* webView = reinterpret_cast<WebKitWebView*>(data); @@ -154,7 +154,8 @@ void PasteboardHelperGtk::writeClipboardContents(GtkClipboard* clipboard, gpoint GtkTargetEntry* table = gtk_target_table_new_from_list(list, &numberOfTargets); if (numberOfTargets > 0 && table) { - settingClipboard = true; + settingClipboardDataObject = dataObject; + settingClipboardData = data; // Protect the web view from being destroyed before one of the clipboard callbacks // is called. Balanced in both getClipboardContentsCallback and @@ -168,7 +169,8 @@ void PasteboardHelperGtk::writeClipboardContents(GtkClipboard* clipboard, gpoint if (!succeeded) g_object_unref(webView); - settingClipboard = false; + settingClipboardDataObject = 0; + settingClipboardData = 0; } else gtk_clipboard_clear(clipboard); diff --git a/WebKit/gtk/docs/webkitgtk-docs.sgml b/WebKit/gtk/docs/webkitgtk-docs.sgml index d61a4fd..77f3482 100644 --- a/WebKit/gtk/docs/webkitgtk-docs.sgml +++ b/WebKit/gtk/docs/webkitgtk-docs.sgml @@ -100,4 +100,7 @@ <index id="index-1.1.18" role="1.1.18"> <title>Index of new symbols in 1.1.18</title> </index> + <index id="index-1.1.20" role="1.1.20"> + <title>Index of new symbols in 1.1.20</title> + </index> </book> diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog index 205583a..8bbd4de 100644 --- a/WebKit/mac/ChangeLog +++ b/WebKit/mac/ChangeLog @@ -1 +1,38 @@ +2010-02-01 Shinichiro Hamaji <hamaji@chromium.org> + + Reviewed by Eric Seidel. + + Provide a way to get page number with layoutTestController + https://bugs.webkit.org/show_bug.cgi?id=33840 + + * Misc/WebCoreStatistics.h: + * Misc/WebCoreStatistics.mm: + (-[WebFrame pageNumberForElement:element:pageWidth:]): + +2010-01-29 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig + Oliver Hunt. + + Bug 34346 - With JSC bindings, make processingUserGesture work with events in Isolated Worlds + + Pass processeing user gensture flag to media play/pause methods. + + * WebView/WebVideoFullscreenHUDWindowController.mm: + (-[WebVideoFullscreenHUDWindowController setPlaying:]): + +2010-02-01 Dan Bernstein <mitz@apple.com> + + Reviewed by Anders Carlsson. + + <rdar://problem/7044385> Crash at NetscapePlugInStreamLoader::didReceiveResponse() + + The crash was caused by having two streams with a streamID of 1. + + * Plugins/Hosted/NetscapePluginInstanceProxy.mm: + (WebKit::NetscapePluginInstanceProxy::NetscapePluginInstanceProxy): Fixed a typo. Now + correctly increments m_currentURLRequestID to account for the manual stream. + (WebKit::NetscapePluginInstanceProxy::disconnectStream): If the stream is the manual stream, + null it out instead of trying to remove it from the map. Added an assertion. + (WebKit::NetscapePluginInstanceProxy::loadRequest): Added an assertion. + == Rolled over to ChangeLog-2010-01-29 == diff --git a/WebKit/mac/Misc/WebCoreStatistics.h b/WebKit/mac/Misc/WebCoreStatistics.h index 7a189ae..6c45fb9 100644 --- a/WebKit/mac/Misc/WebCoreStatistics.h +++ b/WebKit/mac/Misc/WebCoreStatistics.h @@ -84,4 +84,5 @@ @interface WebFrame (WebKitDebug) - (NSString *)renderTreeAsExternalRepresentation; - (NSString *)counterValueForElement:(DOMElement*)element; +- (int)pageNumberForElement:(DOMElement*)element:(float)pageWidthInPixels:(float)pageHeightInPixels; @end diff --git a/WebKit/mac/Misc/WebCoreStatistics.mm b/WebKit/mac/Misc/WebCoreStatistics.mm index f204ddb..b18ee29 100644 --- a/WebKit/mac/Misc/WebCoreStatistics.mm +++ b/WebKit/mac/Misc/WebCoreStatistics.mm @@ -40,6 +40,7 @@ #import <WebCore/IconDatabase.h> #import <WebCore/JSDOMWindow.h> #import <WebCore/PageCache.h> +#import <WebCore/PrintContext.h> #import <WebCore/RenderTreeAsText.h> #import <WebCore/RenderView.h> @@ -250,4 +251,9 @@ using namespace WebCore; return counterValueForElement(core(element)); } +- (int)pageNumberForElement:(DOMElement*)element:(float)pageWidthInPixels:(float)pageHeightInPixels +{ + return PrintContext::pageNumberForElement(core(element), FloatSize(pageWidthInPixels, pageHeightInPixels)); +} + @end diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm index 187b0ea..e4fe1d2 100644 --- a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm +++ b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm @@ -126,7 +126,7 @@ NetscapePluginInstanceProxy::NetscapePluginInstanceProxy(NetscapePluginHostProxy if (fullFramePlugin) { // For full frame plug-ins, the first requestID will always be the one for the already // open stream. - ++m_currentRequestID; + ++m_currentURLRequestID; } // Assign a plug-in ID. @@ -261,6 +261,12 @@ bool NetscapePluginInstanceProxy::cancelStreamLoad(uint32_t streamID, NPReason r void NetscapePluginInstanceProxy::disconnectStream(HostedNetscapePluginStream* stream) { + if (stream == m_manualStream) { + m_manualStream = 0; + return; + } + + ASSERT(m_streams.get(stream->streamID()) == stream); m_streams.remove(stream->streamID()); } @@ -655,6 +661,7 @@ NPError NetscapePluginInstanceProxy::loadRequest(NSURLRequest *request, const ch } else { RefPtr<HostedNetscapePluginStream> stream = HostedNetscapePluginStream::create(this, requestID, request); + ASSERT(!m_streams.contains(requestID)); m_streams.add(requestID, stream); stream->start(); } diff --git a/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm b/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm index 82cb1bf..83e2d09 100644 --- a/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm +++ b/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm @@ -578,13 +578,15 @@ static NSTextField *createTimeTextField(NSRect frame) - (void)setPlaying:(BOOL)playing { - if (![_delegate mediaElement]) + HTMLMediaElement* mediaElement = [_delegate mediaElement]; + + if (!mediaElement) return; if (playing) - [_delegate mediaElement]->play(); + mediaElement->play(mediaElement->processingUserGesture()); else - [_delegate mediaElement]->pause(); + mediaElement->pause(mediaElement->processingUserGesture()); } static NSString *timeToString(double time) diff --git a/WebKit/qt/Api/qwebpage.cpp b/WebKit/qt/Api/qwebpage.cpp index 7e3b084..ea2401b 100644 --- a/WebKit/qt/Api/qwebpage.cpp +++ b/WebKit/qt/Api/qwebpage.cpp @@ -105,6 +105,7 @@ #include <QStyle> #include <QSysInfo> #include <QTextCharFormat> +#include <QTextDocument> #include <QNetworkAccessManager> #include <QNetworkRequest> #if defined(Q_WS_X11) @@ -1871,7 +1872,7 @@ void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg) { Q_UNUSED(frame) #ifndef QT_NO_MESSAGEBOX - QMessageBox::information(view(), tr("JavaScript Alert - %1").arg(mainFrame()->url().host()), msg, QMessageBox::Ok); + QMessageBox::information(view(), tr("JavaScript Alert - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QMessageBox::Ok); #endif } @@ -1887,7 +1888,7 @@ bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg) #ifdef QT_NO_MESSAGEBOX return true; #else - return QMessageBox::Yes == QMessageBox::information(view(), tr("JavaScript Confirm - %1").arg(mainFrame()->url().host()), msg, QMessageBox::Yes, QMessageBox::No); + return QMessageBox::Yes == QMessageBox::information(view(), tr("JavaScript Confirm - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QMessageBox::Yes, QMessageBox::No); #endif } @@ -1906,7 +1907,7 @@ bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QStr Q_UNUSED(frame) bool ok = false; #ifndef QT_NO_INPUTDIALOG - QString x = QInputDialog::getText(view(), tr("JavaScript Prompt - %1").arg(mainFrame()->url().host()), msg, QLineEdit::Normal, defaultValue, &ok); + QString x = QInputDialog::getText(view(), tr("JavaScript Prompt - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QLineEdit::Normal, defaultValue, &ok); if (ok && result) *result = x; #endif diff --git a/WebKit/qt/ChangeLog b/WebKit/qt/ChangeLog index 170665a..e63ee86 100644 --- a/WebKit/qt/ChangeLog +++ b/WebKit/qt/ChangeLog @@ -1,3 +1,78 @@ +2010-02-03 Andras Becsi <abecsi@webkit.org> + + Unreviewed build fix. + + [Qt] Roll-out r54281 because it broke the build on the Qt Release bot. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::QGraphicsWebViewPrivate): + (QGraphicsWebViewPrivate::markForSync): + (QGraphicsWebViewPrivate::update): + (QGraphicsWebView::paint): + +2010-02-02 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Ariya Hidayat. + + Do not use a proxy widget for the QComboBox on Maemo 5, as it + is not working properly and it is not needed at all, as the + comboboxes comes up in their full width on the screen and + do not depend on view. + + * WebCoreSupport/QtFallbackWebPopup.cpp: + (WebCore::QtFallbackWebPopup::show): + +2010-02-02 Jessie Berlin <jberlin@webkit.org> + + Rubber Stamped by Holger Freyther. + + [Qt] Fix style issue identified in bug: + https://bugs.webkit.org/show_bug.cgi?id=34329 + + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientWebPage::InspectorClientWebPage): + Fix indentation. + +2010-02-01 Jessie Berlin <jberlin@webkit.org> + + Reviewed by Holger Freyther. + + [Qt] Enable inspecting the Web Inspector in QtLauncher + + https://bugs.webkit.org/show_bug.cgi?id=34329 + + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientWebPage::InspectorClientWebPage): + Allow the DeveloperExtrasEnabled setting to default to true for the page containing the Web Inspector. + +2010-02-02 Andreas Kling <andreas.kling@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Display HTML tags verbatim in JS alert/confirm/prompt boxes + + https://bugs.webkit.org/show_bug.cgi?id=34429 + + * Api/qwebpage.cpp: + (QWebPage::javaScriptAlert): + (QWebPage::javaScriptConfirm): + (QWebPage::javaScriptPrompt): + +2010-02-02 Noam Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Enable a way to measure FPS in QGVLauncher + run QGVLauncher with --show-fps to see ongoing fps measurements + This is not meant as accurate FPS, but rather as a way to find + improvements/regressions + https://bugs.webkit.org/show_bug.cgi?id=34450 + + * QGVLauncher/main.cpp: + (MainView::MainView): initialize FPS values + (MainView::paintEvent): count a painted frame here + (MainView::printFps): we print the fps with qDebug every 5 seconds. + 2010-01-29 Ben Murdoch <benm@google.com> Reviewed by Dimitri Glazkov. diff --git a/WebKit/qt/QGVLauncher/main.cpp b/WebKit/qt/QGVLauncher/main.cpp index eefff7f..0536af5 100644 --- a/WebKit/qt/QGVLauncher/main.cpp +++ b/WebKit/qt/QGVLauncher/main.cpp @@ -125,12 +125,22 @@ public: MainView(QWidget* parent) : QGraphicsView(parent) , m_mainWidget(0) + , m_measureFps(QApplication::instance()->arguments().contains("--show-fps")) + , m_numTotalPaints(0) + , m_numPaintsSinceLastMeasure(0) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setFrameShape(QFrame::NoFrame); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + if (m_measureFps) { + QTimer* fpsTimer = new QTimer(this); + fpsTimer->setInterval(5000); + m_totalStartTime = m_startTime = QTime::currentTime(); + connect(fpsTimer, SIGNAL(timeout()), this, SLOT(printFps())); + fpsTimer->start(); + } } void setMainWidget(QGraphicsWidget* widget) @@ -149,6 +159,15 @@ public: m_mainWidget->setGeometry(rect); } + void paintEvent(QPaintEvent* event) + { + QGraphicsView::paintEvent(event); + if (m_measureFps) { + ++m_numPaintsSinceLastMeasure; + ++m_numTotalPaints; + } + } + void setWaitCursor() { m_mainWidget->setCursor(Qt::WaitCursor); @@ -195,11 +214,29 @@ public slots: emit flipRequest(); } + void printFps() + { + // note that this might have a bug if you measure right around midnight, but we can live with that + QTime now = QTime::currentTime(); + int msecs = m_startTime.msecsTo(now); + int totalMsecs = m_totalStartTime.msecsTo(now); + int totalFps = totalMsecs ? m_numTotalPaints * 1000 / totalMsecs : 0; + int curFps = msecs ? m_numPaintsSinceLastMeasure * 1000 / msecs : 0; + qDebug("[FPS] From start: %d, from last paint: %d", totalFps, curFps); + m_startTime = now; + m_numPaintsSinceLastMeasure = 0; + } + signals: void flipRequest(); private: QGraphicsWidget* m_mainWidget; + bool m_measureFps; + int m_numTotalPaints; + int m_numPaintsSinceLastMeasure; + QTime m_startTime; + QTime m_totalStartTime; }; class SharedScene : public QSharedData { diff --git a/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp b/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp index 1caf96d..4927ea8 100644 --- a/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp @@ -58,9 +58,8 @@ class InspectorClientWebPage : public QWebPage { friend class InspectorClientQt; public: InspectorClientWebPage(QObject* parent = 0) - : QWebPage(parent) + : QWebPage(parent) { - settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, false); } QWebPage* createWindow(QWebPage::WebWindowType) diff --git a/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.cpp b/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.cpp index 7ee2b7c..c553c45 100644 --- a/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.cpp +++ b/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.cpp @@ -95,6 +95,15 @@ void QtFallbackWebPopup::show() { populate(); m_combo->setCurrentIndex(currentIndex()); + +#if defined(Q_WS_MAEMO_5) + // Comboboxes with Qt on Maemo 5 come up in their full width on the screen, so neither + // the proxy widget, nor the coordinates are needed. + m_combo->setParent(pageClient()->ownerWidget()); + m_combo->showPopup(); + return; +#endif + QRect rect = geometry(); if (QGraphicsWebView *webView = qobject_cast<QGraphicsWebView*>(pageClient()->pluginParent())) { if (!m_proxy) { @@ -110,16 +119,11 @@ void QtFallbackWebPopup::show() } - // QCursor::pos() is not a great idea for a touch screen, but we don't need the coordinates - // as comboboxes with Qt on Maemo 5 come up in their full width on the screen. - // On the other platforms it's okay to use QCursor::pos(). -#if defined(Q_WS_MAEMO_5) - m_combo->showPopup(); -#else + // QCursor::pos() is not a great idea for a touch screen, but as Maemo 5 is handled + // separately above, this should be okay. QMouseEvent event(QEvent::MouseButtonPress, QCursor::pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QCoreApplication::sendEvent(m_combo, &event); -#endif } void QtFallbackWebPopup::hide() diff --git a/WebKit/win/ChangeLog b/WebKit/win/ChangeLog index 6cc5d6e..36d3144 100644 --- a/WebKit/win/ChangeLog +++ b/WebKit/win/ChangeLog @@ -1,3 +1,67 @@ +2010-02-03 Brian Weinstein <bweinstein@apple.com> + + Reviewed by Steve Falkenburg. + + Scroll does not work with IBM Thinkpad. + <https://bugs.webkit.org/show_bug.cgi?id=14227> + <rdar://7142545> + + When initializing the WebView, add two scrollbar Windows inside of + our WebView, to allow it to receive WM_VSCROLL and WM_HSCROLL events. + (similar to what Firefox did in: <https://bugzilla.mozilla.org/show_bug.cgi?id=507222>. + + Only do this if the user has installed some kind of Trackpoint driver, using an algorithm + like <https://bugzilla.mozilla.org/show_bug.cgi?id=514927>. + + Also, add code to handle WM_HSCROLL and WM_VSCROLL messages to scroll + the WebView. + + * WebView.cpp: + (WebView::verticalScroll): Handle the WM_VSCROLL messages, and scroll up and down + by lines or pages. + (WebView::horizontalScroll): Handle the WM_HSCROLL messages, and scroll left or right + by lines or pages. + (WebView::WebViewWndProc): Add cases for WM_VSCROLL and WM_HSCROLL. + (WebView::initWithFrame): Call shouldInitializeTrackPointHack, and if we should, create + vertical and horizontal scrollbars to receive WM_VSCROLL and WM_HSCROLL messages. + (WebView::shouldInitializeTrackPointHack): Check if there is a registry key for + the some kind of IBM Trackpoint driver. + * WebView.h: + +2010-02-02 Steve Falkenburg <sfalken@apple.com> + + Reviewed by Darin Adler. + + Copyright year updating for Windows version resources should be automatic + https://bugs.webkit.org/show_bug.cgi?id=34503 + + * WebKit.vcproj/WebKit.rc: + +2010-02-02 Adam Roben <aroben@apple.com> + + Stop copying WebCore's IDL files from SRCROOT to OBJROOT + + WebKit doesn't use these anymore (as of r52921). + + Part of Bug 34496: Clean up WebCore's IDL/script copying + <https://bugs.webkit.org/show_bug.cgi?id=34496> + + Reviewed by Steve Falkenburg. + + * WebKit.vcproj/WebKit.make: + +2010-01-29 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig + Oliver Hunt. + + Bug 34346 - With JSC bindings, make processingUserGesture work with events in Isolated Worlds + + Pass processeing user gensture flag to media play/pause methods. + + * FullscreenVideoController.cpp: + (FullscreenVideoController::play): + (FullscreenVideoController::pause): + 2010-01-29 Brian Weinstein <bweinstein@apple.com> Reviewed by Adam Roben. diff --git a/WebKit/win/FullscreenVideoController.cpp b/WebKit/win/FullscreenVideoController.cpp index 6b8e5ac..dbfc794 100644 --- a/WebKit/win/FullscreenVideoController.cpp +++ b/WebKit/win/FullscreenVideoController.cpp @@ -243,13 +243,13 @@ bool FullscreenVideoController::canPlay() const void FullscreenVideoController::play() { if (m_mediaElement) - m_mediaElement->play(); + m_mediaElement->play(m_mediaElement->processingUserGesture()); } void FullscreenVideoController::pause() { if (m_mediaElement) - m_mediaElement->pause(); + m_mediaElement->pause(m_mediaElement->processingUserGesture()); } float FullscreenVideoController::volume() const diff --git a/WebKit/win/WebKit.vcproj/WebKit.make b/WebKit/win/WebKit.vcproj/WebKit.make index 072d724..6c2ce85 100755 --- a/WebKit/win/WebKit.vcproj/WebKit.make +++ b/WebKit/win/WebKit.vcproj/WebKit.make @@ -8,7 +8,6 @@ install: set WebKitLibrariesDir=$(SRCROOT)\AppleInternal set WebKitOutputDir=$(OBJROOT) set PRODUCTION=1 - xcopy "$(SRCROOT)\AppleInternal\obj\WebKit\DOMInterfaces\*" "$(OBJROOT)\obj\WebKit\DOMInterfaces" /e/v/i/h/y devenv "WebKit.submit.sln" /rebuild $(BUILDSTYLE) -xcopy "$(OBJROOT)\bin\*.exe" "$(DSTROOT)\AppleInternal\bin\" /e/v/i/h/y xcopy "$(OBJROOT)\bin\*.pdb" "$(DSTROOT)\AppleInternal\bin\" /e/v/i/h/y diff --git a/WebKit/win/WebKit.vcproj/WebKit.rc b/WebKit/win/WebKit.vcproj/WebKit.rc index fa57ca3..92d1e6c 100644 --- a/WebKit/win/WebKit.vcproj/WebKit.rc +++ b/WebKit/win/WebKit.vcproj/WebKit.rc @@ -42,7 +42,7 @@ BEGIN VALUE "FileVersion", __VERSION_TEXT__ VALUE "CompanyName", "Apple Inc." VALUE "InternalName", "WebKit" - VALUE "LegalCopyright", "Copyright Apple Inc. 2003-2010" + VALUE "LegalCopyright", "Copyright Apple Inc. 2003-" __COPYRIGHT_YEAR_END_TEXT__ VALUE "OriginalFilename", "WebKit.dll" VALUE "ProductName", "WebKit" VALUE "ProductVersion", __BUILD_NUMBER_SHORT__ diff --git a/WebKit/win/WebView.cpp b/WebKit/win/WebView.cpp index 4d67110..6144532 100644 --- a/WebKit/win/WebView.cpp +++ b/WebKit/win/WebView.cpp @@ -1589,6 +1589,66 @@ bool WebView::mouseWheel(WPARAM wParam, LPARAM lParam, bool isMouseHWheel) return coreFrame->eventHandler()->handleWheelEvent(wheelEvent); } +bool WebView::verticalScroll(WPARAM wParam, LPARAM /*lParam*/) +{ + ScrollDirection direction; + ScrollGranularity granularity; + switch (LOWORD(wParam)) { + case SB_LINEDOWN: + granularity = ScrollByLine; + direction = ScrollDown; + break; + case SB_LINEUP: + granularity = ScrollByLine; + direction = ScrollUp; + break; + case SB_PAGEDOWN: + granularity = ScrollByDocument; + direction = ScrollDown; + break; + case SB_PAGEUP: + granularity = ScrollByDocument; + direction = ScrollUp; + break; + default: + return false; + break; + } + + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + return frame->eventHandler()->scrollRecursively(direction, granularity); +} + +bool WebView::horizontalScroll(WPARAM wParam, LPARAM /*lParam*/) +{ + ScrollDirection direction; + ScrollGranularity granularity; + switch (LOWORD(wParam)) { + case SB_LINELEFT: + granularity = ScrollByLine; + direction = ScrollLeft; + break; + case SB_LINERIGHT: + granularity = ScrollByLine; + direction = ScrollRight; + break; + case SB_PAGELEFT: + granularity = ScrollByDocument; + direction = ScrollLeft; + break; + case SB_PAGERIGHT: + granularity = ScrollByDocument; + direction = ScrollRight; + break; + default: + return false; + } + + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + return frame->eventHandler()->scrollRecursively(direction, granularity); +} + + bool WebView::execCommand(WPARAM wParam, LPARAM /*lParam*/) { Frame* frame = m_page->focusController()->focusedOrMainFrame(); @@ -2155,6 +2215,12 @@ LRESULT CALLBACK WebView::WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, break; __fallthrough; + case WM_VSCROLL: + handled = webView->verticalScroll(wParam, lParam); + break; + case WM_HSCROLL: + handled = webView->horizontalScroll(wParam, lParam); + break; default: handled = false; break; @@ -2387,6 +2453,34 @@ static void WebKitSetApplicationCachePathIfNecessary() initialized = true; } + +bool WebView::shouldInitializeTrackPointHack() +{ + static bool shouldCreateScrollbars; + static bool hasRunTrackPointCheck; + + if (hasRunTrackPointCheck) + return shouldCreateScrollbars; + + hasRunTrackPointCheck = true; + const TCHAR trackPointKeys[][50] = { TEXT("Software\\Lenovo\\TrackPoint"), + TEXT("Software\\Lenovo\\UltraNav"), + TEXT("Software\\Alps\\Apoint\\TrackPoint"), + TEXT("Software\\Synaptics\\SynTPEnh\\UltraNavUSB"), + TEXT("Software\\Synaptics\\SynTPEnh\\UltraNavPS2") }; + + for (int i = 0; i < 5; ++i) { + HKEY trackPointKey; + int readKeyResult = ::RegOpenKeyEx(HKEY_CURRENT_USER, trackPointKeys[i], 0, KEY_READ, &trackPointKey); + ::RegCloseKey(trackPointKey); + if (readKeyResult == ERROR_SUCCESS) { + shouldCreateScrollbars = true; + return shouldCreateScrollbars; + } + } + + return shouldCreateScrollbars; +} HRESULT STDMETHODCALLTYPE WebView::initWithFrame( /* [in] */ RECT frame, @@ -2404,6 +2498,14 @@ HRESULT STDMETHODCALLTYPE WebView::initWithFrame( frame.left, frame.top, frame.right - frame.left, frame.bottom - frame.top, m_hostWindow ? m_hostWindow : HWND_MESSAGE, 0, gInstance, 0); ASSERT(::IsWindow(m_viewWindow)); + if (shouldInitializeTrackPointHack()) { + // If we detected a registry key belonging to a TrackPoint driver, then create fake trackpoint + // scrollbars, so the WebView will receive WM_VSCROLL and WM_HSCROLL messages. We create one + // vertical scrollbar and one horizontal to allow for receiving both types of messages. + ::CreateWindow(TEXT("SCROLLBAR"), TEXT("FAKETRACKPOINTHSCROLLBAR"), WS_CHILD | WS_VISIBLE | SBS_HORZ, 0, 0, 0, 0, m_viewWindow, 0, gInstance, 0); + ::CreateWindow(TEXT("SCROLLBAR"), TEXT("FAKETRACKPOINTVSCROLLBAR"), WS_CHILD | WS_VISIBLE | SBS_VERT, 0, 0, 0, 0, m_viewWindow, 0, gInstance, 0); + } + hr = registerDragDrop(); if (FAILED(hr)) return hr; diff --git a/WebKit/win/WebView.h b/WebKit/win/WebView.h index cd857a8..56fb40c 100644 --- a/WebKit/win/WebView.h +++ b/WebKit/win/WebView.h @@ -793,6 +793,8 @@ public: bool onUninitMenuPopup(WPARAM, LPARAM); void performContextMenuAction(WPARAM, LPARAM, bool byPosition); bool mouseWheel(WPARAM, LPARAM, bool isMouseHWheel); + bool verticalScroll(WPARAM, LPARAM); + bool horizontalScroll(WPARAM, LPARAM); bool gesture(WPARAM, LPARAM); bool gestureNotify(WPARAM, LPARAM); bool execCommand(WPARAM wParam, LPARAM lParam); @@ -919,6 +921,8 @@ protected: LRESULT onIMERequestReconvertString(WebCore::Frame*, RECONVERTSTRING*); bool developerExtrasEnabled() const; + bool shouldInitializeTrackPointHack(); + // AllWebViewSet functions void addToAllWebViewsSet(); void removeFromAllWebViewsSet(); diff --git a/WebKit/wx/ChangeLog b/WebKit/wx/ChangeLog index 1c7adf2..26d14d6 100644 --- a/WebKit/wx/ChangeLog +++ b/WebKit/wx/ChangeLog @@ -1,3 +1,17 @@ +2010-02-03 Kevin Watters <kevinwatters@gmail.com> + + Reviewed by Kevin Ollivier. + + Add wxWebKitWindowFeatures and have createWindow send a notification for + clients to handle. + + https://bugs.webkit.org/show_bug.cgi?id=34542 + + * WebKitSupport/ChromeClientWx.cpp: + (WebCore::wkFeaturesforWindowFeatures): + (WebCore::ChromeClientWx::createWindow): + * WebView.h: + 2010-01-27 Kevin Watters <kevinwatters@gmail.com> Reviewed by Kevin Ollivier. diff --git a/WebKit/wx/WebKitSupport/ChromeClientWx.cpp b/WebKit/wx/WebKitSupport/ChromeClientWx.cpp index 17f6f43..4d524bc 100644 --- a/WebKit/wx/WebKitSupport/ChromeClientWx.cpp +++ b/WebKit/wx/WebKitSupport/ChromeClientWx.cpp @@ -37,6 +37,7 @@ #include "FrameLoadRequest.h" #include "NotImplemented.h" #include "PlatformString.h" +#include "WindowFeatures.h" #include <stdio.h> @@ -53,6 +54,21 @@ namespace WebCore { +wxWebKitWindowFeatures wkFeaturesforWindowFeatures(const WindowFeatures& features) +{ + wxWebKitWindowFeatures wkFeatures; + wkFeatures.menuBarVisible = features.menuBarVisible; + wkFeatures.statusBarVisible = features.statusBarVisible; + wkFeatures.toolBarVisible = features.toolBarVisible; + wkFeatures.locationBarVisible = features.locationBarVisible; + wkFeatures.scrollbarsVisible = features.scrollbarsVisible; + wkFeatures.resizable = features.resizable; + wkFeatures.fullscreen = features.fullscreen; + wkFeatures.dialog = features.dialog; + + return wkFeatures; +} + ChromeClientWx::ChromeClientWx(wxWebView* webView) { m_webView = webView; @@ -115,22 +131,21 @@ void ChromeClientWx::focusedNodeChanged(Node*) { } -Page* ChromeClientWx::createWindow(Frame*, const FrameLoadRequest& request, const WindowFeatures&) +Page* ChromeClientWx::createWindow(Frame*, const FrameLoadRequest& request, const WindowFeatures& features) { - - // FIXME: Create a EVT_WEBKIT_NEW_WINDOW event, and only run this code - // when that event is not handled. - Page* myPage = 0; - wxWebBrowserShell* newFrame = new wxWebBrowserShell(wxTheApp->GetAppName()); + wxWebViewNewWindowEvent wkEvent(m_webView); + wkEvent.SetURL(request.resourceRequest().url().string()); - if (newFrame->webview) { - newFrame->webview->LoadURL(request.resourceRequest().url().string()); - newFrame->Show(true); - - WebViewPrivate* impl = newFrame->webview->m_impl; - if (impl) - myPage = impl->page; + wxWebKitWindowFeatures wkFeatures = wkFeaturesforWindowFeatures(features); + wkEvent.SetWindowFeatures(wkFeatures); + + if (m_webView->GetEventHandler()->ProcessEvent(wkEvent)) { + if (wxWebView* webView = wkEvent.GetWebView()) { + WebViewPrivate* impl = webView->m_impl; + if (impl) + myPage = impl->page; + } } return myPage; diff --git a/WebKit/wx/WebView.h b/WebKit/wx/WebView.h index 7d923a3..9a6546c 100644 --- a/WebKit/wx/WebView.h +++ b/WebKit/wx/WebView.h @@ -203,7 +203,6 @@ public: const wxString& password = wxEmptyString); wxWebSettings GetWebSettings(); - wxWebKitParseMode GetParseMode() const; protected: @@ -304,6 +303,30 @@ private: wxString m_url; }; +class WXDLLIMPEXP_WEBKIT wxWebKitWindowFeatures +{ +public: + wxWebKitWindowFeatures() + : menuBarVisible(true) + , statusBarVisible(true) + , toolBarVisible(true) + , locationBarVisible(true) + , scrollbarsVisible(true) + , resizable(true) + , fullscreen(false) + , dialog(false) + { } + + bool menuBarVisible; + bool statusBarVisible; + bool toolBarVisible; + bool locationBarVisible; + bool scrollbarsVisible; + bool resizable; + bool fullscreen; + bool dialog; +}; + class WXDLLIMPEXP_WEBKIT wxWebViewNewWindowEvent : public wxCommandEvent { #ifndef SWIG @@ -315,11 +338,17 @@ public: void SetURL(const wxString& url) { m_url = url; } wxString GetTargetName() const { return m_targetName; } void SetTargetName(const wxString& name) { m_targetName = name; } + wxWebView* GetWebView() { return m_webView; } + void SetWebView(wxWebView* webView) { m_webView = webView; } + wxWebKitWindowFeatures GetWindowFeatures() { return m_features; } + void SetWindowFeatures(wxWebKitWindowFeatures features) { m_features = features; } wxWebViewNewWindowEvent( wxWindow* win = static_cast<wxWindow*>(NULL)); wxEvent *Clone(void) const { return new wxWebViewNewWindowEvent(*this); } private: + wxWebView* m_webView; + wxWebKitWindowFeatures m_features; wxString m_url; wxString m_targetName; }; |