diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/API/gtk')
157 files changed, 11683 insertions, 3455 deletions
diff --git a/Source/WebKit2/UIProcess/API/gtk/APIWebsiteDataStoreGtk.cpp b/Source/WebKit2/UIProcess/API/gtk/APIWebsiteDataStoreGtk.cpp new file mode 100644 index 000000000..1bc99fb15 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/APIWebsiteDataStoreGtk.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 "APIWebsiteDataStore.h" + +#include <WebCore/FileSystem.h> + +namespace API { + +String WebsiteDataStore::defaultApplicationCacheDirectory() +{ + return cacheDirectoryFileSystemRepresentation("webkitgtk" G_DIR_SEPARATOR_S "applications"); +} + +// FIXME: The other directories in this file are shared between all applications using WebKitGTK+. +// Why is only this directory namespaced to a particular application? +String WebsiteDataStore::defaultNetworkCacheDirectory() +{ + return cacheDirectoryFileSystemRepresentation(WebCore::pathByAppendingComponent(WebCore::stringFromFileSystemRepresentation(g_get_prgname()), "WebKitCache")); +} + +String WebsiteDataStore::defaultIndexedDBDatabaseDirectory() +{ + return websiteDataDirectoryFileSystemRepresentation("webkitgtk" G_DIR_SEPARATOR_S "databases" G_DIR_SEPARATOR_S "indexeddb"); +} + +String WebsiteDataStore::defaultLocalStorageDirectory() +{ + return websiteDataDirectoryFileSystemRepresentation("webkitgtk" G_DIR_SEPARATOR_S "localstorage"); +} + +String WebsiteDataStore::defaultMediaKeysStorageDirectory() +{ + return websiteDataDirectoryFileSystemRepresentation("webkitgtk" G_DIR_SEPARATOR_S "mediakeys"); +} + +String WebsiteDataStore::defaultWebSQLDatabaseDirectory() +{ + return websiteDataDirectoryFileSystemRepresentation("webkitgtk" G_DIR_SEPARATOR_S "databases"); +} + +String WebsiteDataStore::defaultResourceLoadStatisticsDirectory() +{ + return websiteDataDirectoryFileSystemRepresentation("webkitgtk" G_DIR_SEPARATOR_S "ResourceLoadStatistics"); +} + +String WebsiteDataStore::cacheDirectoryFileSystemRepresentation(const String& directoryName) +{ + return WebCore::pathByAppendingComponent(WebCore::stringFromFileSystemRepresentation(g_get_user_cache_dir()), directoryName); +} + +String WebsiteDataStore::websiteDataDirectoryFileSystemRepresentation(const String& directoryName) +{ + return WebCore::pathByAppendingComponent(WebCore::stringFromFileSystemRepresentation(g_get_user_data_dir()), directoryName); +} + +WebKit::WebsiteDataStore::Configuration WebsiteDataStore::defaultDataStoreConfiguration() +{ + WebKit::WebsiteDataStore::Configuration configuration; + + configuration.applicationCacheDirectory = defaultApplicationCacheDirectory(); + configuration.networkCacheDirectory = defaultNetworkCacheDirectory(); + + configuration.webSQLDatabaseDirectory = defaultWebSQLDatabaseDirectory(); + configuration.localStorageDirectory = defaultLocalStorageDirectory(); + configuration.mediaKeysStorageDirectory = defaultMediaKeysStorageDirectory(); + configuration.resourceLoadStatisticsDirectory = defaultResourceLoadStatisticsDirectory(); + + return configuration; +} + +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp index 872a274c9..815855091 100644 --- a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp @@ -31,16 +31,22 @@ #include "DrawingAreaProxyImpl.h" #include "NativeWebKeyboardEvent.h" #include "NativeWebMouseEvent.h" +#include "NativeWebWheelEvent.h" #include "NotImplemented.h" -#include "WebContext.h" +#include "WebColorPickerGtk.h" #include "WebContextMenuProxyGtk.h" #include "WebEventFactory.h" +#include "WebKitColorChooser.h" #include "WebKitWebViewBasePrivate.h" +#include "WebKitWebViewPrivate.h" #include "WebPageProxy.h" #include "WebPopupMenuProxyGtk.h" +#include "WebProcessPool.h" +#include <WebCore/CairoUtilities.h> #include <WebCore/Cursor.h> #include <WebCore/EventNames.h> #include <WebCore/GtkUtilities.h> +#include <WebCore/RefPtrCairo.h> #include <wtf/text/CString.h> #include <wtf/text/WTFString.h> @@ -53,47 +59,26 @@ PageClientImpl::PageClientImpl(GtkWidget* viewWidget) { } -PageClientImpl::~PageClientImpl() -{ -} - -void PageClientImpl::getEditorCommandsForKeyEvent(const NativeWebKeyboardEvent& event, const AtomicString& eventType, Vector<WTF::String>& commandList) -{ - ASSERT(eventType == eventNames().keydownEvent || eventType == eventNames().keypressEvent); - - KeyBindingTranslator::EventType type = eventType == eventNames().keydownEvent ? - KeyBindingTranslator::KeyDown : KeyBindingTranslator::KeyPress; - m_keyBindingTranslator.getEditorCommandsForKeyEvent(const_cast<GdkEventKey*>(&event.nativeEvent()->key), type, commandList); -} - // PageClient's pure virtual functions std::unique_ptr<DrawingAreaProxy> PageClientImpl::createDrawingAreaProxy() { - return std::make_unique<DrawingAreaProxyImpl>(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_viewWidget))); + return std::make_unique<DrawingAreaProxyImpl>(*webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_viewWidget))); } -void PageClientImpl::setViewNeedsDisplay(const WebCore::IntRect& rect) +void PageClientImpl::setViewNeedsDisplay(const WebCore::Region& region) { - gtk_widget_queue_draw_area(m_viewWidget, rect.x(), rect.y(), rect.width(), rect.height()); + gtk_widget_queue_draw_region(m_viewWidget, toCairoRegion(region).get()); } -void PageClientImpl::displayView() +void PageClientImpl::requestScroll(const WebCore::FloatPoint&, const WebCore::IntPoint&, bool) { notImplemented(); } -void PageClientImpl::scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) -{ - setViewNeedsDisplay(scrollRect); -} - WebCore::IntSize PageClientImpl::viewSize() { - if (!gtk_widget_get_realized(m_viewWidget)) - return IntSize(); - GtkAllocation allocation; - gtk_widget_get_allocation(m_viewWidget, &allocation); - return IntSize(allocation.width, allocation.height); + auto* drawingArea = static_cast<DrawingAreaProxyImpl*>(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_viewWidget))->drawingArea()); + return drawingArea ? drawingArea->size() : IntSize(); } bool PageClientImpl::isViewWindowActive() @@ -116,14 +101,14 @@ bool PageClientImpl::isViewInWindow() return webkitWebViewBaseIsInWindow(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); } -void PageClientImpl::PageClientImpl::processDidCrash() +void PageClientImpl::PageClientImpl::processDidExit() { notImplemented(); } void PageClientImpl::didRelaunchProcess() { - notImplemented(); + webkitWebViewBaseDidRelaunchWebProcess(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); } void PageClientImpl::toolTipChanged(const String&, const String& newToolTip) @@ -131,7 +116,7 @@ void PageClientImpl::toolTipChanged(const String&, const String& newToolTip) webkitWebViewBaseSetTooltipText(WEBKIT_WEB_VIEW_BASE(m_viewWidget), newToolTip.utf8().data()); } -void PageClientImpl::setCursor(const Cursor& cursor) +void PageClientImpl::setCursor(const WebCore::Cursor& cursor) { if (!gtk_widget_get_realized(m_viewWidget)) return; @@ -147,7 +132,7 @@ void PageClientImpl::setCursor(const Cursor& cursor) gdk_window_set_cursor(window, newCursor); } -void PageClientImpl::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves) +void PageClientImpl::setCursorHiddenUntilMouseMoves(bool /* hiddenUntilMouseMoves */) { notImplemented(); } @@ -189,7 +174,7 @@ FloatRect PageClientImpl::convertToUserSpace(const FloatRect& viewRect) return viewRect; } -IntPoint PageClientImpl::screenToWindow(const IntPoint& point) +IntPoint PageClientImpl::screenToRootView(const IntPoint& point) { IntPoint widgetPositionOnScreen = convertWidgetPointToScreenPoint(m_viewWidget, IntPoint()); IntPoint result(point); @@ -197,7 +182,7 @@ IntPoint PageClientImpl::screenToWindow(const IntPoint& point) return result; } -IntRect PageClientImpl::windowToScreen(const IntRect& rect) +IntRect PageClientImpl::rootViewToScreen(const IntRect& rect) { return IntRect(convertWidgetPointToScreenPoint(m_viewWidget, rect.location()), rect.size()); } @@ -214,49 +199,41 @@ void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool gtk_main_do_event(event.nativeEvent()); } -PassRefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy* page) +RefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy& page) { return WebPopupMenuProxyGtk::create(m_viewWidget, page); } -PassRefPtr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy* page) -{ - return WebContextMenuProxyGtk::create(m_viewWidget, page); -} - -#if ENABLE(INPUT_TYPE_COLOR) -PassRefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy*, const WebCore::Color&, const WebCore::IntRect&) +std::unique_ptr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy& page, const ContextMenuContextData& context, const UserData& userData) { - notImplemented(); - return 0; + return std::make_unique<WebContextMenuProxyGtk>(m_viewWidget, page, context, userData); } -#endif -void PageClientImpl::setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut, bool animate) +RefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy* page, const WebCore::Color& color, const WebCore::IntRect& rect) { - notImplemented(); + if (WEBKIT_IS_WEB_VIEW(m_viewWidget)) + return WebKitColorChooser::create(*page, color, rect); + return WebColorPickerGtk::create(*page, color, rect); } -#if USE(ACCELERATED_COMPOSITING) -void PageClientImpl::enterAcceleratedCompositingMode(const LayerTreeContext&) +void PageClientImpl::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) { - notImplemented(); + webkitWebViewBaseEnterAcceleratedCompositingMode(WEBKIT_WEB_VIEW_BASE(m_viewWidget), layerTreeContext); } void PageClientImpl::exitAcceleratedCompositingMode() { - notImplemented(); + webkitWebViewBaseExitAcceleratedCompositingMode(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); } -void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext&) +void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) { - notImplemented(); + webkitWebViewBaseUpdateAcceleratedCompositingMode(WEBKIT_WEB_VIEW_BASE(m_viewWidget), layerTreeContext); } -#endif // USE(ACCELERATED_COMPOSITING) void PageClientImpl::pageClosed() { - notImplemented(); + webkitWebViewBasePageClosed(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); } void PageClientImpl::preferencesDidChange() @@ -264,15 +241,27 @@ void PageClientImpl::preferencesDidChange() notImplemented(); } -void PageClientImpl::updateTextInputState() +void PageClientImpl::selectionDidChange() { webkitWebViewBaseUpdateTextInputState(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); + if (WEBKIT_IS_WEB_VIEW(m_viewWidget)) + webkitWebViewSelectionDidChange(WEBKIT_WEB_VIEW(m_viewWidget)); +} + +void PageClientImpl::didChangeContentSize(const IntSize& size) +{ + webkitWebViewBaseSetContentsSize(WEBKIT_WEB_VIEW_BASE(m_viewWidget), size); } #if ENABLE(DRAG_SUPPORT) -void PageClientImpl::startDrag(const WebCore::DragData& dragData, PassRefPtr<ShareableBitmap> dragImage) +void PageClientImpl::startDrag(Ref<SelectionData>&& selection, DragOperation dragOperation, RefPtr<ShareableBitmap>&& dragImage) { - webkitWebViewBaseStartDrag(WEBKIT_WEB_VIEW_BASE(m_viewWidget), dragData, dragImage); + WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(m_viewWidget); + webkitWebViewBaseDragAndDropHandler(webView).startDrag(WTFMove(selection), dragOperation, WTFMove(dragImage)); + + // A drag starting should prevent a double-click from happening. This might + // happen if a drag is followed very quickly by another click (like in the WTR). + webkitWebViewBaseResetClickCounter(webView); } #endif @@ -281,7 +270,7 @@ void PageClientImpl::handleDownloadRequest(DownloadProxy* download) webkitWebViewBaseHandleDownloadRequest(WEBKIT_WEB_VIEW_BASE(m_viewWidget), download); } -void PageClientImpl::didCommitLoadForMainFrame() +void PageClientImpl::didCommitLoadForMainFrame(const String& /* mimeType */, bool /* useCustomContentProvider */ ) { webkitWebViewBaseResetClickCounter(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); } @@ -319,23 +308,30 @@ void PageClientImpl::exitFullScreen() webkitWebViewBaseExitFullScreen(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); } -void PageClientImpl::beganEnterFullScreen(const IntRect& initialFrame, const IntRect& finalFrame) +void PageClientImpl::beganEnterFullScreen(const IntRect& /* initialFrame */, const IntRect& /* finalFrame */) { notImplemented(); } -void PageClientImpl::beganExitFullScreen(const IntRect& initialFrame, const IntRect& finalFrame) +void PageClientImpl::beganExitFullScreen(const IntRect& /* initialFrame */, const IntRect& /* finalFrame */) { notImplemented(); } #endif // ENABLE(FULLSCREEN_API) +#if ENABLE(TOUCH_EVENTS) void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled) { if (wasEventHandled) return; +#if HAVE(GTK_GESTURES) + GestureController& gestureController = webkitWebViewBaseGestureController(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); + if (gestureController.handleEvent(event.nativeEvent())) + return; +#endif + // Emulate pointer events if unhandled. const GdkEvent* touchEvent = event.nativeEvent(); @@ -380,5 +376,77 @@ void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& event, bool w gtk_widget_event(m_viewWidget, pointerEvent.get()); } +#endif // ENABLE(TOUCH_EVENTS) + +void PageClientImpl::wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent& event) +{ + webkitWebViewBaseForwardNextWheelEvent(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); + gtk_main_do_event(event.nativeEvent()); +} + +void PageClientImpl::didFinishLoadingDataForCustomContentProvider(const String&, const IPC::DataReference&) +{ +} + +void PageClientImpl::navigationGestureDidBegin() +{ +} + +void PageClientImpl::navigationGestureWillEnd(bool, WebBackForwardListItem&) +{ +} + +void PageClientImpl::navigationGestureDidEnd(bool, WebBackForwardListItem&) +{ +} + +void PageClientImpl::navigationGestureDidEnd() +{ +} + +void PageClientImpl::willRecordNavigationSnapshot(WebBackForwardListItem&) +{ +} + +void PageClientImpl::didRemoveNavigationGestureSnapshot() +{ +} + +void PageClientImpl::didFirstVisuallyNonEmptyLayoutForMainFrame() +{ +} + +void PageClientImpl::didFinishLoadForMainFrame() +{ +} + +void PageClientImpl::didSameDocumentNavigationForMainFrame(SameDocumentNavigationType) +{ +} + +void PageClientImpl::didChangeBackgroundColor() +{ +} + +void PageClientImpl::refView() +{ + g_object_ref(m_viewWidget); +} + +void PageClientImpl::derefView() +{ + g_object_unref(m_viewWidget); +} + +#if ENABLE(VIDEO) && USE(GSTREAMER) +bool PageClientImpl::decidePolicyForInstallMissingMediaPluginsPermissionRequest(InstallMissingMediaPluginsPermissionRequest& request) +{ + if (!WEBKIT_IS_WEB_VIEW(m_viewWidget)) + return false; + + webkitWebViewRequestInstallMissingMediaPlugins(WEBKIT_WEB_VIEW(m_viewWidget), request); + return true; +} +#endif } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h index c420beec7..8d4a31070 100644 --- a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h +++ b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h @@ -1,3 +1,4 @@ + /* * Copyright (C) 2010 Apple Inc. All rights reserved. * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. @@ -29,13 +30,12 @@ #define PageClientImpl_h #include "DefaultUndoController.h" -#include "KeyBindingTranslator.h" #include "PageClient.h" #include "WebFullScreenManagerProxy.h" #include "WebPageProxy.h" -#include "WindowsKeyboardCodes.h" #include <WebCore/IntSize.h> #include <gtk/gtk.h> +#include <memory> namespace WebKit { @@ -48,87 +48,106 @@ class PageClientImpl : public PageClient #endif { public: - ~PageClientImpl(); - static PassOwnPtr<PageClientImpl> create(GtkWidget* viewWidget) - { - return adoptPtr(new PageClientImpl(viewWidget)); - } + explicit PageClientImpl(GtkWidget*); GtkWidget* viewWidget() { return m_viewWidget; } private: - explicit PageClientImpl(GtkWidget*); - // PageClient - virtual std::unique_ptr<DrawingAreaProxy> createDrawingAreaProxy() override; - virtual void setViewNeedsDisplay(const WebCore::IntRect&) override; - virtual void displayView() override; - virtual bool canScrollView() override { return false; } - virtual void scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) override; - virtual WebCore::IntSize viewSize() override; - virtual bool isViewWindowActive() override; - virtual bool isViewFocused() override; - virtual bool isViewVisible() override; - virtual bool isViewInWindow() override; - virtual void processDidCrash() override; - virtual void didRelaunchProcess() override; - virtual void pageClosed() override; - virtual void preferencesDidChange() override; - virtual void toolTipChanged(const WTF::String&, const WTF::String&) override; - virtual void setCursor(const WebCore::Cursor&) override; - virtual void setCursorHiddenUntilMouseMoves(bool) override; - virtual void didChangeViewportProperties(const WebCore::ViewportAttributes&) override; - virtual void registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo) override; - virtual void clearAllEditCommands() override; - virtual bool canUndoRedo(WebPageProxy::UndoOrRedo) override; - virtual void executeUndoRedo(WebPageProxy::UndoOrRedo) override; - virtual WebCore::FloatRect convertToDeviceSpace(const WebCore::FloatRect&) override; - virtual WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&) override; - virtual WebCore::IntPoint screenToWindow(const WebCore::IntPoint&) override; - virtual WebCore::IntRect windowToScreen(const WebCore::IntRect&) override; - virtual void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool wasEventHandled) override; - virtual PassRefPtr<WebPopupMenuProxy> createPopupMenuProxy(WebPageProxy*) override; - virtual PassRefPtr<WebContextMenuProxy> createContextMenuProxy(WebPageProxy*) override; + std::unique_ptr<DrawingAreaProxy> createDrawingAreaProxy() override; + void setViewNeedsDisplay(const WebCore::Region&) override; + void requestScroll(const WebCore::FloatPoint& scrollPosition, const WebCore::IntPoint& scrollOrigin, bool isProgrammaticScroll) override; + WebCore::IntSize viewSize() override; + bool isViewWindowActive() override; + bool isViewFocused() override; + bool isViewVisible() override; + bool isViewInWindow() override; + void processDidExit() override; + void didRelaunchProcess() override; + void pageClosed() override; + void preferencesDidChange() override; + void toolTipChanged(const WTF::String&, const WTF::String&) override; + void setCursor(const WebCore::Cursor&) override; + void setCursorHiddenUntilMouseMoves(bool) override; + void didChangeViewportProperties(const WebCore::ViewportAttributes&) override; + void registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo) override; + void clearAllEditCommands() override; + bool canUndoRedo(WebPageProxy::UndoOrRedo) override; + void executeUndoRedo(WebPageProxy::UndoOrRedo) override; + WebCore::FloatRect convertToDeviceSpace(const WebCore::FloatRect&) override; + WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&) override; + WebCore::IntPoint screenToRootView(const WebCore::IntPoint&) override; + WebCore::IntRect rootViewToScreen(const WebCore::IntRect&) override; + void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool wasEventHandled) override; + RefPtr<WebPopupMenuProxy> createPopupMenuProxy(WebPageProxy&) override; + std::unique_ptr<WebContextMenuProxy> createContextMenuProxy(WebPageProxy&, const ContextMenuContextData&, const UserData&) override; #if ENABLE(INPUT_TYPE_COLOR) - virtual PassRefPtr<WebColorPicker> createColorPicker(WebPageProxy*, const WebCore::Color& intialColor, const WebCore::IntRect&) override; + RefPtr<WebColorPicker> createColorPicker(WebPageProxy*, const WebCore::Color& intialColor, const WebCore::IntRect&) override; #endif - virtual void setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut, bool animate) override; - virtual void getEditorCommandsForKeyEvent(const NativeWebKeyboardEvent&, const AtomicString&, Vector<WTF::String>&) override; - virtual void updateTextInputState() override; + void selectionDidChange() override; #if ENABLE(DRAG_SUPPORT) - virtual void startDrag(const WebCore::DragData&, PassRefPtr<ShareableBitmap> dragImage) override; + void startDrag(Ref<WebCore::SelectionData>&&, WebCore::DragOperation, RefPtr<ShareableBitmap>&& dragImage) override; #endif -#if USE(ACCELERATED_COMPOSITING) - virtual void enterAcceleratedCompositingMode(const LayerTreeContext&) override; - virtual void exitAcceleratedCompositingMode() override; - virtual void updateAcceleratedCompositingMode(const LayerTreeContext&) override; -#endif + void enterAcceleratedCompositingMode(const LayerTreeContext&) override; + void exitAcceleratedCompositingMode() override; + void updateAcceleratedCompositingMode(const LayerTreeContext&) override; - virtual void handleDownloadRequest(DownloadProxy*) override; - virtual void didCommitLoadForMainFrame() override; + void handleDownloadRequest(DownloadProxy*) override; + void didChangeContentSize(const WebCore::IntSize&) override; + void didCommitLoadForMainFrame(const String& mimeType, bool useCustomContentProvider) override; + void didFailLoadForMainFrame() override { } // Auxiliary Client Creation #if ENABLE(FULLSCREEN_API) - virtual WebFullScreenManagerProxyClient& fullScreenManagerProxyClient() final; + WebFullScreenManagerProxyClient& fullScreenManagerProxyClient() final; #endif #if ENABLE(FULLSCREEN_API) // WebFullScreenManagerProxyClient - virtual void closeFullScreenManager() override; - virtual bool isFullScreen() override; - virtual void enterFullScreen() override; - virtual void exitFullScreen() override; - virtual void beganEnterFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) override; - virtual void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) override; + void closeFullScreenManager() override; + bool isFullScreen() override; + void enterFullScreen() override; + void exitFullScreen() override; + void beganEnterFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) override; + void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) override; +#endif + + void didFinishLoadingDataForCustomContentProvider(const String& suggestedFilename, const IPC::DataReference&) override; + + void navigationGestureDidBegin() override; + void navigationGestureWillEnd(bool, WebBackForwardListItem&) override; + void navigationGestureDidEnd(bool, WebBackForwardListItem&) override; + void navigationGestureDidEnd() override; + void willRecordNavigationSnapshot(WebBackForwardListItem&) override; + void didRemoveNavigationGestureSnapshot() override; + + void didFirstVisuallyNonEmptyLayoutForMainFrame() override; + void didFinishLoadForMainFrame() override; + void didSameDocumentNavigationForMainFrame(SameDocumentNavigationType) override; + +#if ENABLE(TOUCH_EVENTS) + void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled) override; +#endif + + void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) override; + + void didChangeBackgroundColor() override; + + void refView() override; + void derefView() override; + + void didRestoreScrollPosition() override { } + +#if ENABLE(VIDEO) && USE(GSTREAMER) + bool decidePolicyForInstallMissingMediaPluginsPermissionRequest(InstallMissingMediaPluginsPermissionRequest&) override; #endif - virtual void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled) override; + WebCore::UserInterfaceLayoutDirection userInterfaceLayoutDirection() override { return WebCore::UserInterfaceLayoutDirection::LTR; } // Members of PageClientImpl class GtkWidget* m_viewWidget; DefaultUndoController m_undoController; - WebCore::KeyBindingTranslator m_keyBindingTranslator; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.cpp index 43cd83ac0..b0bb2b854 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.cpp @@ -25,12 +25,17 @@ #include "WebKitCredentialPrivate.h" #include "WebKitPrivate.h" #include "WebKitWebView.h" +#include <glib/gi18n-lib.h> +#include <wtf/text/CString.h> using namespace WebKit; struct _WebKitAuthenticationDialogPrivate { GRefPtr<WebKitAuthenticationRequest> request; - GtkWidget* authWidget; + CredentialStorageMode credentialStorageMode; + GtkWidget* loginEntry; + GtkWidget* passwordEntry; + GtkWidget* rememberCheckButton; GtkWidget* defaultButton; unsigned long authenticationCancelledID; GRefPtr<GtkStyleContext> styleContext; @@ -41,7 +46,15 @@ WEBKIT_DEFINE_TYPE(WebKitAuthenticationDialog, webkit_authentication_dialog, GTK static void okButtonClicked(GtkButton*, WebKitAuthenticationDialog* authDialog) { WebKitAuthenticationDialogPrivate* priv = authDialog->priv; - WebKitCredential* credential = webkitCredentialCreate(webkitAuthenticationWidgetCreateCredential(WEBKIT_AUTHENTICATION_WIDGET(priv->authWidget))); + const char* username = gtk_entry_get_text(GTK_ENTRY(priv->loginEntry)); + const char* password = gtk_entry_get_text(GTK_ENTRY(priv->passwordEntry)); + bool rememberPassword = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->rememberCheckButton)); + + WebCore::CredentialPersistence persistence = rememberPassword && priv->credentialStorageMode == AllowPersistentStorage ? + WebCore::CredentialPersistencePermanent : WebCore::CredentialPersistenceForSession; + + // FIXME: Use a stack allocated WebKitCredential. + WebKitCredential* credential = webkitCredentialCreate(WebCore::Credential(String::fromUTF8(username), String::fromUTF8(password), persistence)); webkit_authentication_request_authenticate(priv->request.get(), credential); webkit_credential_free(credential); gtk_widget_destroy(GTK_WIDGET(authDialog)); @@ -49,7 +62,7 @@ static void okButtonClicked(GtkButton*, WebKitAuthenticationDialog* authDialog) static void cancelButtonClicked(GtkButton*, WebKitAuthenticationDialog* authDialog) { - webkit_authentication_request_authenticate(authDialog->priv->request.get(), 0); + webkit_authentication_request_authenticate(authDialog->priv->request.get(), nullptr); gtk_widget_destroy(GTK_WIDGET(authDialog)); } @@ -58,34 +71,120 @@ static void authenticationCancelled(WebKitAuthenticationRequest*, WebKitAuthenti gtk_widget_destroy(GTK_WIDGET(authDialog)); } -static void webkitAuthenticationDialogInitialize(WebKitAuthenticationDialog* authDialog, CredentialStorageMode credentialStorageMode) +static GtkWidget* createLabelWithLineWrap(const char* text) +{ + GtkWidget* label = gtk_label_new(text); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_label_set_max_width_chars(GTK_LABEL(label), 40); + return label; +} + +static void webkitAuthenticationDialogInitialize(WebKitAuthenticationDialog* authDialog) { GtkWidget* frame = gtk_frame_new(0); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); GtkWidget* vBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); - gtk_container_set_border_width(GTK_CONTAINER(vBox), 5); + gtk_container_set_border_width(GTK_CONTAINER(vBox), 12); + + GtkWidget* label = gtk_label_new(nullptr); + // Title of the HTTP authentication dialog. + GUniquePtr<char> title(g_strdup_printf("<b>%s</b>", _("Authentication Required"))); + gtk_label_set_markup(GTK_LABEL(label), title.get()); + gtk_widget_set_halign(label, GTK_ALIGN_CENTER); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(vBox), label, FALSE, FALSE, 0); GtkWidget* buttonBox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_END); gtk_container_set_border_width(GTK_CONTAINER(buttonBox), 5); gtk_box_set_spacing(GTK_BOX(buttonBox), 6); - GtkWidget* button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + GtkWidget* button = gtk_button_new_with_mnemonic(_("_Cancel")); g_signal_connect(button, "clicked", G_CALLBACK(cancelButtonClicked), authDialog); gtk_box_pack_end(GTK_BOX(buttonBox), button, FALSE, TRUE, 0); gtk_widget_show(button); - button = gtk_button_new_from_stock(GTK_STOCK_OK); - authDialog->priv->defaultButton = button; + WebKitAuthenticationDialogPrivate* priv = authDialog->priv; + button = gtk_button_new_with_mnemonic(_("_Authenticate")); + priv->defaultButton = button; g_signal_connect(button, "clicked", G_CALLBACK(okButtonClicked), authDialog); gtk_widget_set_can_default(button, TRUE); gtk_box_pack_end(GTK_BOX(buttonBox), button, FALSE, TRUE, 0); gtk_widget_show(button); - authDialog->priv->authWidget = webkitAuthenticationWidgetNew(webkitAuthenticationRequestGetAuthenticationChallenge(authDialog->priv->request.get())->core(), credentialStorageMode); - gtk_box_pack_start(GTK_BOX(vBox), authDialog->priv->authWidget, TRUE, TRUE, 0); - gtk_widget_show(authDialog->priv->authWidget); + GtkWidget* authBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12); + gtk_container_set_border_width(GTK_CONTAINER(authBox), 5); + + const WebCore::AuthenticationChallenge& challenge = webkitAuthenticationRequestGetAuthenticationChallenge(priv->request.get())->core(); + // Prompt on the HTTP authentication dialog. + GUniquePtr<char> prompt(g_strdup_printf(_("Authentication required by %s:%i"), + challenge.protectionSpace().host().utf8().data(), challenge.protectionSpace().port())); + label = createLabelWithLineWrap(prompt.get()); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(authBox), label, FALSE, FALSE, 0); + + String realm = challenge.protectionSpace().realm(); + if (!realm.isEmpty()) { + // Label on the HTTP authentication dialog. %s is a (probably English) message from the website. + GUniquePtr<char> message(g_strdup_printf(_("The site says: “%s”"), realm.utf8().data())); + label = createLabelWithLineWrap(message.get()); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(authBox), label, FALSE, FALSE, 0); + } + + // Check button on the HTTP authentication dialog. + priv->rememberCheckButton = gtk_check_button_new_with_mnemonic(_("_Remember password")); + gtk_label_set_line_wrap(GTK_LABEL(gtk_bin_get_child(GTK_BIN(priv->rememberCheckButton))), TRUE); + + priv->loginEntry = gtk_entry_new(); + gtk_widget_set_hexpand(priv->loginEntry, TRUE); + gtk_entry_set_activates_default(GTK_ENTRY(priv->loginEntry), TRUE); + gtk_widget_show(priv->loginEntry); + + // Entry on the HTTP authentication dialog. + GtkWidget* loginLabel = gtk_label_new_with_mnemonic(_("_Username")); + gtk_label_set_mnemonic_widget(GTK_LABEL(loginLabel), priv->loginEntry); + gtk_widget_set_halign(loginLabel, GTK_ALIGN_END); + gtk_style_context_add_class(gtk_widget_get_style_context(loginLabel), GTK_STYLE_CLASS_DIM_LABEL); + gtk_widget_show(loginLabel); + + priv->passwordEntry = gtk_entry_new(); + gtk_widget_set_hexpand(priv->passwordEntry, TRUE); + gtk_entry_set_activates_default(GTK_ENTRY(priv->passwordEntry), TRUE); + gtk_widget_show(priv->passwordEntry); + + // Entry on the HTTP authentication dialog. + GtkWidget* passwordLabel = gtk_label_new_with_mnemonic(_("_Password")); + gtk_label_set_mnemonic_widget(GTK_LABEL(passwordLabel), priv->passwordEntry); + gtk_widget_set_halign(passwordLabel, GTK_ALIGN_END); + gtk_style_context_add_class(gtk_widget_get_style_context(passwordLabel), GTK_STYLE_CLASS_DIM_LABEL); + gtk_widget_show(passwordLabel); + + GtkWidget* grid = gtk_grid_new(); + gtk_grid_set_column_spacing(GTK_GRID(grid), 6); + gtk_grid_set_row_spacing(GTK_GRID(grid), 6); + gtk_grid_attach(GTK_GRID(grid), loginLabel, 0, 0, 1, 1); + gtk_grid_attach(GTK_GRID(grid), priv->loginEntry, 1, 0, 1, 1); + gtk_grid_attach(GTK_GRID(grid), passwordLabel, 0, 1, 1, 1); + gtk_grid_attach(GTK_GRID(grid), priv->passwordEntry, 1, 1, 1, 1); + gtk_grid_attach(GTK_GRID(grid), priv->rememberCheckButton, 1, 2, 1, 1); + gtk_widget_show(grid); + gtk_box_pack_start(GTK_BOX(authBox), grid, FALSE, FALSE, 0); + + gtk_entry_set_visibility(GTK_ENTRY(priv->passwordEntry), FALSE); + gtk_widget_set_visible(priv->rememberCheckButton, priv->credentialStorageMode != DisallowPersistentStorage && !realm.isEmpty()); + + const WebCore::Credential& credentialFromPersistentStorage = challenge.proposedCredential(); + if (!credentialFromPersistentStorage.isEmpty()) { + gtk_entry_set_text(GTK_ENTRY(priv->loginEntry), credentialFromPersistentStorage.user().utf8().data()); + gtk_entry_set_text(GTK_ENTRY(priv->passwordEntry), credentialFromPersistentStorage.password().utf8().data()); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->rememberCheckButton), TRUE); + } + + gtk_box_pack_start(GTK_BOX(vBox), authBox, TRUE, TRUE, 0); + gtk_widget_show(authBox); gtk_box_pack_end(GTK_BOX(vBox), buttonBox, FALSE, TRUE, 0); gtk_widget_show(buttonBox); @@ -103,10 +202,19 @@ static gboolean webkitAuthenticationDialogDraw(GtkWidget* widget, cairo_t* cr) { WebKitAuthenticationDialogPrivate* priv = WEBKIT_AUTHENTICATION_DIALOG(widget)->priv; - gtk_style_context_save(priv->styleContext.get()); - gtk_style_context_add_class(priv->styleContext.get(), GTK_STYLE_CLASS_BACKGROUND); - gtk_render_background(priv->styleContext.get(), cr, 0, 0, gtk_widget_get_allocated_width(widget), gtk_widget_get_allocated_height(widget)); - gtk_style_context_restore(priv->styleContext.get()); + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + cairo_set_source_rgba(cr, 0, 0, 0, 0.5); + cairo_paint(cr); + + if (GtkWidget* child = gtk_bin_get_child(GTK_BIN(widget))) { + GtkAllocation allocation; + gtk_widget_get_allocation(child, &allocation); + + gtk_style_context_save(priv->styleContext.get()); + gtk_style_context_add_class(priv->styleContext.get(), GTK_STYLE_CLASS_BACKGROUND); + gtk_render_background(priv->styleContext.get(), cr, allocation.x, allocation.y, allocation.width, allocation.height); + gtk_style_context_restore(priv->styleContext.get()); + } GTK_WIDGET_CLASS(webkit_authentication_dialog_parent_class)->draw(widget, cr); @@ -116,11 +224,33 @@ static gboolean webkitAuthenticationDialogDraw(GtkWidget* widget, cairo_t* cr) static void webkitAuthenticationDialogMap(GtkWidget* widget) { WebKitAuthenticationDialogPrivate* priv = WEBKIT_AUTHENTICATION_DIALOG(widget)->priv; + gtk_widget_grab_focus(priv->loginEntry); gtk_widget_grab_default(priv->defaultButton); GTK_WIDGET_CLASS(webkit_authentication_dialog_parent_class)->map(widget); } +static void webkitAuthenticationDialogSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) +{ + GTK_WIDGET_CLASS(webkit_authentication_dialog_parent_class)->size_allocate(widget, allocation); + + GtkWidget* child = gtk_bin_get_child(GTK_BIN(widget)); + if (!child) + return; + + GtkRequisition naturalSize; + gtk_widget_get_preferred_size(child, 0, &naturalSize); + + GtkAllocation childAllocation; + gtk_widget_get_allocation(child, &childAllocation); + + childAllocation.x += (allocation->width - naturalSize.width) / 2; + childAllocation.y += (allocation->height - naturalSize.height) / 2; + childAllocation.width = naturalSize.width; + childAllocation.height = naturalSize.height; + gtk_widget_size_allocate(child, &childAllocation); +} + static void webkitAuthenticationDialogConstructed(GObject* object) { G_OBJECT_CLASS(webkit_authentication_dialog_parent_class)->constructed(object); @@ -153,12 +283,14 @@ static void webkit_authentication_dialog_class_init(WebKitAuthenticationDialogCl GtkWidgetClass* widgetClass = GTK_WIDGET_CLASS(klass); widgetClass->draw = webkitAuthenticationDialogDraw; widgetClass->map = webkitAuthenticationDialogMap; + widgetClass->size_allocate = webkitAuthenticationDialogSizeAllocate; } GtkWidget* webkitAuthenticationDialogNew(WebKitAuthenticationRequest* request, CredentialStorageMode mode) { WebKitAuthenticationDialog* authDialog = WEBKIT_AUTHENTICATION_DIALOG(g_object_new(WEBKIT_TYPE_AUTHENTICATION_DIALOG, NULL)); authDialog->priv->request = request; - webkitAuthenticationDialogInitialize(authDialog, mode); + authDialog->priv->credentialStorageMode = mode; + webkitAuthenticationDialogInitialize(authDialog); return GTK_WIDGET(authDialog); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.h b/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.h index e5e62a7bd..0e5071f53 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.h @@ -21,10 +21,13 @@ #define WebKitAuthenticationDialog_h #include "WebKitAuthenticationRequest.h" -#include "WebKitAuthenticationWidget.h" -#include "WebKitWebView.h" #include <gtk/gtk.h> +enum CredentialStorageMode { + AllowPersistentStorage, // The user is asked whether to store credential information. + DisallowPersistentStorage // Credential information is only kept in the session. +}; + G_BEGIN_DECLS #define WEBKIT_TYPE_AUTHENTICATION_DIALOG (webkit_authentication_dialog_get_type()) diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationRequest.cpp index 6f0c3707e..8e2e72561 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationRequest.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationRequest.cpp @@ -67,18 +67,35 @@ struct _WebKitAuthenticationRequestPrivate { static guint signals[LAST_SIGNAL] = { 0, }; -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_DEFAULT, ProtectionSpaceAuthenticationSchemeDefault); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_HTTP_BASIC, ProtectionSpaceAuthenticationSchemeHTTPBasic); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_HTTP_DIGEST, ProtectionSpaceAuthenticationSchemeHTTPDigest); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_HTML_FORM, ProtectionSpaceAuthenticationSchemeHTMLForm); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_NTLM, ProtectionSpaceAuthenticationSchemeNTLM); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_NEGOTIATE, ProtectionSpaceAuthenticationSchemeNegotiate); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_REQUESTED, ProtectionSpaceAuthenticationSchemeClientCertificateRequested); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_SERVER_TRUST_EVALUATION_REQUESTED, ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_UNKNOWN, ProtectionSpaceAuthenticationSchemeUnknown); - WEBKIT_DEFINE_TYPE(WebKitAuthenticationRequest, webkit_authentication_request, G_TYPE_OBJECT) +static inline WebKitAuthenticationScheme toWebKitAuthenticationScheme(WebCore::ProtectionSpaceAuthenticationScheme coreScheme) +{ + switch (coreScheme) { + case WebCore::ProtectionSpaceAuthenticationSchemeDefault: + return WEBKIT_AUTHENTICATION_SCHEME_DEFAULT; + case WebCore::ProtectionSpaceAuthenticationSchemeHTTPBasic: + return WEBKIT_AUTHENTICATION_SCHEME_HTTP_BASIC; + case WebCore::ProtectionSpaceAuthenticationSchemeHTTPDigest: + return WEBKIT_AUTHENTICATION_SCHEME_HTTP_DIGEST; + case WebCore::ProtectionSpaceAuthenticationSchemeHTMLForm: + return WEBKIT_AUTHENTICATION_SCHEME_HTML_FORM; + case WebCore::ProtectionSpaceAuthenticationSchemeNTLM: + return WEBKIT_AUTHENTICATION_SCHEME_NTLM; + case WebCore::ProtectionSpaceAuthenticationSchemeNegotiate: + return WEBKIT_AUTHENTICATION_SCHEME_NEGOTIATE; + case WebCore::ProtectionSpaceAuthenticationSchemeClientCertificateRequested: + return WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_REQUESTED; + case WebCore::ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested: + return WEBKIT_AUTHENTICATION_SCHEME_SERVER_TRUST_EVALUATION_REQUESTED; + case WebCore::ProtectionSpaceAuthenticationSchemeUnknown: + return WEBKIT_AUTHENTICATION_SCHEME_UNKNOWN; + default: + ASSERT_NOT_REACHED(); + return WEBKIT_AUTHENTICATION_SCHEME_DEFAULT; + } +} + static void webkitAuthenticationRequestDispose(GObject* object) { WebKitAuthenticationRequest* request = WEBKIT_AUTHENTICATION_REQUEST(object); @@ -144,7 +161,7 @@ gboolean webkit_authentication_request_can_save_credentials(WebKitAuthentication { g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), FALSE); -#if ENABLE(CREDENTIAL_STORAGE) +#if USE(LIBSECRET) return !request->priv->privateBrowsingEnabled; #else return FALSE; @@ -168,7 +185,7 @@ WebKitCredential* webkit_authentication_request_get_proposed_credential(WebKitAu { g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), 0); - const WebCore::Credential& credential = request->priv->authenticationChallenge->proposedCredential()->core(); + const WebCore::Credential& credential = request->priv->authenticationChallenge->proposedCredential()->credential(); if (credential.isEmpty()) return 0; @@ -244,7 +261,7 @@ WebKitAuthenticationScheme webkit_authentication_request_get_scheme(WebKitAuthen { g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), WEBKIT_AUTHENTICATION_SCHEME_UNKNOWN); - return static_cast<WebKitAuthenticationScheme>(request->priv->authenticationChallenge->protectionSpace()->authenticationScheme()); + return toWebKitAuthenticationScheme(request->priv->authenticationChallenge->protectionSpace()->authenticationScheme()); } /** @@ -295,8 +312,11 @@ void webkit_authentication_request_authenticate(WebKitAuthenticationRequest* req { g_return_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request)); - RefPtr<WebCredential> webCredential = credential ? WebCredential::create(webkitCredentialGetCredential(credential)) : 0; - request->priv->authenticationChallenge->listener()->useCredential(webCredential.get()); + if (credential) + request->priv->authenticationChallenge->listener()->useCredential(WebCredential::create(webkitCredentialGetCredential(credential)).ptr()); + else + request->priv->authenticationChallenge->listener()->useCredential(nullptr); + request->priv->handledRequest = true; } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitAutocleanups.h b/Source/WebKit2/UIProcess/API/gtk/WebKitAutocleanups.h new file mode 100644 index 000000000..c32c099c0 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitAutocleanups.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitAutocleanups_h +#define WebKitAutocleanups_h + +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +#ifndef __GI_SCANNER__ + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitAuthenticationRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitBackForwardList, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitBackForwardListItem, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitColorChooserRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitContextMenu, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitContextMenuItem, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitCookieManager, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitDownload, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitEditorState, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitFaviconDatabase, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitFileChooserRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitFindController, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitFormSubmissionRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitGeolocationPermissionRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitHitTestResult, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitInstallMissingMediaPluginsPermissionRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitNavigationPolicyDecision, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitNotification, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitNotificationPermissionRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPermissionRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPlugin, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPolicyDecision, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPrintCustomWidget, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPrintOperation, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitResponsePolicyDecision, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitSecurityManager, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitSettings, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitURIRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitURIResponse, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitURISchemeRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserContentManager, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserMediaPermissionRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebContext, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebInspector, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebResource, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebView, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebsiteDataManager, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWindowProperties, g_object_unref) + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitCredential, webkit_credential_free) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitJavascriptResult, webkit_javascript_result_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitMimeInfo, webkit_mime_info_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitNavigationAction, webkit_navigation_action_free) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitNetworkProxySettings, webkit_network_proxy_settings_free) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitSecurityOrigin, webkit_security_origin_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserScript, webkit_user_script_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserStyleSheet, webkit_user_style_sheet_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebsiteData, webkit_website_data_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebViewSessionState, webkit_web_view_session_state_unref) + +#endif // __GI_SCANNER__ +#endif // G_DEFINE_AUTOPTR_CLEANUP_FUNC + +#endif // WebKitAutocleanups_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardList.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardList.cpp index 6cbddc8aa..0762d0280 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardList.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardList.cpp @@ -23,7 +23,7 @@ #include "WebKitBackForwardListPrivate.h" #include "WebKitMarshal.h" #include "WebKitPrivate.h" -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> /** * SECTION: WebKitBackForwardList @@ -128,20 +128,25 @@ WebKitBackForwardList* webkitBackForwardListCreate(WebBackForwardList* backForwa return list; } -void webkitBackForwardListChanged(WebKitBackForwardList* backForwardList, WebBackForwardListItem* webAddedItem, API::Array* webRemovedItems) +void webkitBackForwardListChanged(WebKitBackForwardList* backForwardList, WebBackForwardListItem* webAddedItem, const Vector<RefPtr<WebBackForwardListItem>>& webRemovedItems) { WebKitBackForwardListItem* addedItem = webkitBackForwardListGetOrCreateItem(backForwardList, webAddedItem); - GList* removedItems = 0; + GList* removedItems = nullptr; - size_t removedItemsSize = webRemovedItems ? webRemovedItems->size() : 0; WebKitBackForwardListPrivate* priv = backForwardList->priv; - for (size_t i = 0; i < removedItemsSize; ++i) { - WebBackForwardListItem* webItem = static_cast<WebBackForwardListItem*>(webRemovedItems->at(i)); - removedItems = g_list_prepend(removedItems, g_object_ref(G_OBJECT(priv->itemsMap.get(webItem).get()))); - priv->itemsMap.remove(webItem); + for (auto& webItem : webRemovedItems) { + // After a session restore, we still don't have wrappers for the newly added items, so it would be possible that + // the removed items are not in the map. In that case we create a wrapper now to pass it the changed signal, but + // without adding it to the item map. See https://bugs.webkit.org/show_bug.cgi?id=153233. + GRefPtr<WebKitBackForwardListItem> removedItem = priv->itemsMap.get(webItem.get()); + if (removedItem) { + removedItems = g_list_prepend(removedItems, g_object_ref(removedItem.get())); + priv->itemsMap.remove(webItem.get()); + } else + removedItems = g_list_prepend(removedItems, webkitBackForwardListItemGetOrCreate(webItem.get())); } - g_signal_emit(backForwardList, signals[CHANGED], 0, addedItem, removedItems, NULL); + g_signal_emit(backForwardList, signals[CHANGED], 0, addedItem, removedItems, nullptr); g_list_free_full(removedItems, static_cast<GDestroyNotify>(g_object_unref)); } @@ -252,8 +257,8 @@ GList* webkit_back_forward_list_get_back_list_with_limit(WebKitBackForwardList* g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0); WebKitBackForwardListPrivate* priv = backForwardList->priv; - RefPtr<API::Array> apiArray = priv->backForwardItems->backListAsAPIArrayWithLimit(limit); - return webkitBackForwardListCreateList(backForwardList, apiArray.get()); + Ref<API::Array> apiArray = priv->backForwardItems->backListAsAPIArrayWithLimit(limit); + return webkitBackForwardListCreateList(backForwardList, apiArray.ptr()); } /** @@ -283,6 +288,6 @@ GList* webkit_back_forward_list_get_forward_list_with_limit(WebKitBackForwardLis g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0); WebKitBackForwardListPrivate* priv = backForwardList->priv; - RefPtr<API::Array> apiArray = priv->backForwardItems->forwardListAsAPIArrayWithLimit(limit); - return webkitBackForwardListCreateList(backForwardList, apiArray.get()); + Ref<API::Array> apiArray = priv->backForwardItems->forwardListAsAPIArrayWithLimit(limit); + return webkitBackForwardListCreateList(backForwardList, apiArray.ptr()); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListItem.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListItem.cpp index ae18b05ec..b295c9904 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListItem.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListItem.cpp @@ -23,7 +23,8 @@ #include "WebKitBackForwardListPrivate.h" #include "WebKitPrivate.h" #include <wtf/HashMap.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -48,7 +49,7 @@ struct _WebKitBackForwardListItemPrivate { WEBKIT_DEFINE_TYPE(WebKitBackForwardListItem, webkit_back_forward_list_item, G_TYPE_INITIALLY_UNOWNED) -static void webkit_back_forward_list_item_class_init(WebKitBackForwardListItemClass* listItemClass) +static void webkit_back_forward_list_item_class_init(WebKitBackForwardListItemClass*) { } @@ -56,13 +57,13 @@ typedef HashMap<WebBackForwardListItem*, WebKitBackForwardListItem*> HistoryItem static HistoryItemsMap& historyItemsMap() { - DEFINE_STATIC_LOCAL(HistoryItemsMap, itemsMap, ()); + static NeverDestroyed<HistoryItemsMap> itemsMap; return itemsMap; } static void webkitBackForwardListItemFinalized(gpointer webListItem, GObject* finalizedListItem) { - ASSERT(G_OBJECT(historyItemsMap().get(static_cast<WebBackForwardListItem*>(webListItem))) == finalizedListItem); + ASSERT_UNUSED(finalizedListItem, G_OBJECT(historyItemsMap().get(static_cast<WebBackForwardListItem*>(webListItem))) == finalizedListItem); historyItemsMap().remove(static_cast<WebBackForwardListItem*>(webListItem)); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListPrivate.h index ef9052dc9..88ec1d01c 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListPrivate.h @@ -32,6 +32,6 @@ WebKitBackForwardList* webkitBackForwardListCreate(WebKit::WebBackForwardList*); WebKitBackForwardListItem* webkitBackForwardListItemGetOrCreate(WebKit::WebBackForwardListItem*); WebKit::WebBackForwardListItem* webkitBackForwardListItemGetItem(WebKitBackForwardListItem*); -void webkitBackForwardListChanged(WebKitBackForwardList*, WebKit::WebBackForwardListItem* webAddedItem, API::Array* webRemovedItems); +void webkitBackForwardListChanged(WebKitBackForwardList*, WebKit::WebBackForwardListItem* webAddedItem, const Vector<RefPtr<WebKit::WebBackForwardListItem>>&); #endif // WebKitBackForwardListPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitBatteryProvider.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitBatteryProvider.cpp deleted file mode 100644 index 3c1e4c6a8..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitBatteryProvider.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2013 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "WebKitBatteryProvider.h" - -#if ENABLE(BATTERY_STATUS) - -#include "WebBatteryManagerProxy.h" -#include "WebBatteryStatus.h" -#include <limits> - -using namespace WebKit; - -static inline WebKitBatteryProvider* toBatteryProvider(const void* clientInfo) -{ - return static_cast<WebKitBatteryProvider*>(const_cast<void*>(clientInfo)); -} - -static void startUpdatingCallback(WKBatteryManagerRef batteryManager, const void* clientInfo) -{ - toBatteryProvider(clientInfo)->startUpdating(); -} - -static void stopUpdatingCallback(WKBatteryManagerRef batteryManager, const void* clientInfo) -{ - toBatteryProvider(clientInfo)->stopUpdating(); -} - -PassRefPtr<WebKitBatteryProvider> WebKitBatteryProvider::create(WebBatteryManagerProxy* batteryManager) -{ - return adoptRef(new WebKitBatteryProvider(batteryManager)); -} - -WebKitBatteryProvider::WebKitBatteryProvider(WebBatteryManagerProxy* batteryManager) - : m_batteryManager(batteryManager) - , m_provider(this) -{ - ASSERT(batteryManager); - - WKBatteryProviderV0 wkBatteryProvider = { - { - 0, // version - this // clientInfo - }, - startUpdatingCallback, - stopUpdatingCallback - }; - WKBatteryManagerSetProvider(toAPI(batteryManager), &wkBatteryProvider.base); -} - -WebKitBatteryProvider::~WebKitBatteryProvider() -{ - m_provider.stopUpdating(); -} - -void WebKitBatteryProvider::startUpdating() -{ - m_provider.startUpdating(); -} - -void WebKitBatteryProvider::stopUpdating() -{ - m_provider.stopUpdating(); -} - -void WebKitBatteryProvider::updateBatteryStatus(WebCore::BatteryProviderUPowerStatus status, double secondsRemaining, double batteryLevel) -{ - RefPtr<WebBatteryStatus> batteryStatus; - - switch (status) { - case WebCore::NotAvailable: - // When an implementation cannot report battery status, the default values should be used. - batteryStatus = WebBatteryStatus::create(true, std::numeric_limits<double>::infinity(), - std::numeric_limits<double>::infinity(), 1.0); - break; - case WebCore::Charging: - batteryStatus = WebBatteryStatus::create(true, secondsRemaining, 0, batteryLevel); - break; - case WebCore::Discharging: - batteryStatus = WebBatteryStatus::create(false, 0, secondsRemaining, batteryLevel); - break; - default: - ASSERT_NOT_REACHED(); - } - - m_batteryManager->providerUpdateBatteryStatus(batteryStatus.get()); -} - -#endif // ENABLE(BATTERY_STATUS) diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitBatteryProvider.h b/Source/WebKit2/UIProcess/API/gtk/WebKitBatteryProvider.h deleted file mode 100644 index 7f05db6c7..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitBatteryProvider.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2013 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef WebKitBatteryProvider_h -#define WebKitBatteryProvider_h - -#if ENABLE(BATTERY_STATUS) - -#include "WebKitPrivate.h" -#include <WebCore/BatteryProviderUPowerClient.h> -#include <WebCore/BatteryProviderUPower.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> - -namespace WebKit { - -class WebKitBatteryProvider : public RefCounted<WebKitBatteryProvider>, public WebCore::BatteryProviderUPowerClient { -public: - static PassRefPtr<WebKitBatteryProvider> create(WebBatteryManagerProxy*); - virtual ~WebKitBatteryProvider(); - - void startUpdating(); - void stopUpdating(); - -private: - WebKitBatteryProvider(WebBatteryManagerProxy*); - - // WebCore::BatteryProviderUPowerClient - virtual void updateBatteryStatus(WebCore::BatteryProviderUPowerStatus, double secondsRemaining, double batteryLevel); - - RefPtr<WebBatteryManagerProxy> m_batteryManager; - WebCore::BatteryProviderUPower m_provider; -}; - -} - -#endif // ENABLE(BATTERY_STATUS) - -#endif // WebKitBatteryProvider_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCertificateInfo.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitCertificateInfo.cpp deleted file mode 100644 index 12df1aaca..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitCertificateInfo.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2013 Samsung Electronics Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "WebKitCertificateInfo.h" - -#include "WebKitCertificateInfoPrivate.h" -#include <wtf/text/CString.h> - -using namespace WebKit; -using namespace WebCore; - -/** - * SECTION: WebKitCertificateInfo - * @Short_description: Boxed type to encapsulate TLS certificate information - * @Title: WebKitCertificateInfo - * @See_also: #WebKitWebView, #WebKitWebContext - * - * When a client loads a page over HTTPS where there is an underlying TLS error - * WebKit will fire a #WebKitWebView::load-failed-with-tls-errors signal with a - * #WebKitCertificateInfo and the host of the failing URI. - * - * To handle this signal asynchronously you should make a copy of the - * #WebKitCertificateInfo with webkit_certificate_info_copy(). - */ - -G_DEFINE_BOXED_TYPE(WebKitCertificateInfo, webkit_certificate_info, webkit_certificate_info_copy, webkit_certificate_info_free) - -const CertificateInfo& webkitCertificateInfoGetCertificateInfo(WebKitCertificateInfo* info) -{ - ASSERT(info); - return info->certificateInfo; -} - -/** - * webkit_certificate_info_copy: - * @info: a #WebKitCertificateInfo - * - * Make a copy of the #WebKitCertificateInfo. - * - * Returns: (transfer full): A copy of passed in #WebKitCertificateInfo. - * - * Since: 2.4 - */ -WebKitCertificateInfo* webkit_certificate_info_copy(WebKitCertificateInfo* info) -{ - g_return_val_if_fail(info, 0); - - WebKitCertificateInfo* copy = g_slice_new0(WebKitCertificateInfo); - new (copy) WebKitCertificateInfo(info); - return copy; -} - -/** - * webkit_certificate_info_free: - * @info: a #WebKitCertificateInfo - * - * Free the #WebKitCertificateInfo. - * - * Since: 2.4 - */ -void webkit_certificate_info_free(WebKitCertificateInfo* info) -{ - g_return_if_fail(info); - - info->~WebKitCertificateInfo(); - g_slice_free(WebKitCertificateInfo, info); -} - -/** - * webkit_certificate_info_get_tls_certificate: - * @info: a #WebKitCertificateInfo - * - * Get the #GTlsCertificate associated with this - * #WebKitCertificateInfo. - * - * Returns: (transfer none): The certificate of @info. - * - * Since: 2.4 - */ -GTlsCertificate* webkit_certificate_info_get_tls_certificate(WebKitCertificateInfo *info) -{ - g_return_val_if_fail(info, 0); - - return info->certificateInfo.certificate(); -} - -/** - * webkit_certificate_info_get_tls_errors: - * @info: a #WebKitCertificateInfo - * - * Get the #GTlsCertificateFlags verification status associated with this - * #WebKitCertificateInfo. - * - * Returns: The verification status of @info. - * - * Since: 2.4 - */ -GTlsCertificateFlags webkit_certificate_info_get_tls_errors(WebKitCertificateInfo *info) -{ - g_return_val_if_fail(info, static_cast<GTlsCertificateFlags>(0)); - - return info->certificateInfo.tlsErrors(); -} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooser.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooser.cpp new file mode 100644 index 000000000..71919d8f6 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooser.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitColorChooser.h" + +#include "WebKitColorChooserRequestPrivate.h" +#include "WebKitWebViewPrivate.h" +#include <WebCore/Color.h> +#include <WebCore/IntRect.h> + +using namespace WebCore; + +namespace WebKit { + +Ref<WebKitColorChooser> WebKitColorChooser::create(WebPageProxy& page, const WebCore::Color& initialColor, const WebCore::IntRect& rect) +{ + return adoptRef(*new WebKitColorChooser(page, initialColor, rect)); +} + +WebKitColorChooser::WebKitColorChooser(WebPageProxy& page, const Color& initialColor, const IntRect& rect) + : WebColorPickerGtk(page, initialColor, rect) + , m_elementRect(rect) +{ +} + +WebKitColorChooser::~WebKitColorChooser() +{ + endPicker(); +} + +void WebKitColorChooser::endPicker() +{ + if (!m_request) { + WebColorPickerGtk::endPicker(); + return; + } + + webkit_color_chooser_request_finish(m_request.get()); +} + +void WebKitColorChooser::colorChooserRequestFinished(WebKitColorChooserRequest*, WebKitColorChooser* colorChooser) +{ + colorChooser->m_request = nullptr; +} + +void WebKitColorChooser::colorChooserRequestRGBAChanged(WebKitColorChooserRequest* request, GParamSpec*, WebKitColorChooser* colorChooser) +{ + GdkRGBA rgba; + webkit_color_chooser_request_get_rgba(request, &rgba); + colorChooser->didChooseColor(rgba); +} + +void WebKitColorChooser::showColorPicker(const Color& color) +{ + m_initialColor = color; + GRefPtr<WebKitColorChooserRequest> request = adoptGRef(webkitColorChooserRequestCreate(this)); + g_signal_connect(request.get(), "notify::rgba", G_CALLBACK(WebKitColorChooser::colorChooserRequestRGBAChanged), this); + g_signal_connect(request.get(), "finished", G_CALLBACK(WebKitColorChooser::colorChooserRequestFinished), this); + + if (webkitWebViewEmitRunColorChooser(WEBKIT_WEB_VIEW(m_webView), request.get())) + m_request = request; + else + WebColorPickerGtk::showColorPicker(color); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooser.h b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooser.h new file mode 100644 index 000000000..0dc9762c6 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooser.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitColorChooser_h +#define WebKitColorChooser_h + +#include "WebColorPickerGtk.h" +#include "WebKitPrivate.h" +#include <wtf/glib/GRefPtr.h> + +typedef struct _WebKitColorChooserRequest WebKitColorChooserRequest; + +namespace WebCore { +class Color; +class IntRect; +} + +namespace WebKit { + +class WebKitColorChooser final : public WebColorPickerGtk { +public: + static Ref<WebKitColorChooser> create(WebPageProxy&, const WebCore::Color&, const WebCore::IntRect&); + virtual ~WebKitColorChooser(); + + const WebCore::IntRect& elementRect() const { return m_elementRect; } + +private: + WebKitColorChooser(WebPageProxy&, const WebCore::Color&, const WebCore::IntRect&); + + void endPicker() override; + void showColorPicker(const WebCore::Color&) override; + + static void colorChooserRequestFinished(WebKitColorChooserRequest*, WebKitColorChooser*); + static void colorChooserRequestRGBAChanged(WebKitColorChooserRequest*, GParamSpec*, WebKitColorChooser*); + + GRefPtr<WebKitColorChooserRequest> m_request; + WebCore::IntRect m_elementRect; +}; + +} // namespace WebKit + +#endif // WebKitColorChooser_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequest.cpp new file mode 100644 index 000000000..98dad2514 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequest.cpp @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * Copyright (c) 2012, Samsung Electronics + * + * 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. + * + * 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 "WebKitColorChooserRequest.h" + +#include "WebKitColorChooserRequestPrivate.h" +#include <glib/gi18n-lib.h> + +using namespace WebKit; +using namespace WebCore; + +/** + * SECTION: WebKitColorChooserRequest + * @Short_description: A request to open a color chooser + * @Title: WebKitColorChooserRequest + * @See_also: #WebKitWebView + * + * Whenever the user interacts with an <input type='color' /> + * HTML element, WebKit will need to show a dialog to choose a color. For that + * to happen in a general way, instead of just opening a #GtkColorChooser + * (which might be not desirable in some cases, which could prefer to use their + * own color chooser dialog), WebKit will fire the + * #WebKitWebView::run-color-chooser signal with a #WebKitColorChooserRequest + * object, which will allow the client application to specify the color to be + * selected, to inspect the details of the request (e.g. to get initial color) + * and to cancel the request, in case nothing was selected. + * + * In case the client application does not wish to handle this signal, + * WebKit will provide a default handler which will asynchronously run + * a regular #GtkColorChooserDialog for the user to interact with. + */ + +enum { + PROP_0, + + PROP_RGBA +}; + +enum { + FINISHED, + + LAST_SIGNAL +}; + +struct _WebKitColorChooserRequestPrivate { + WebKitColorChooser* colorChooser; + GdkRGBA rgba; + bool handled; +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +WEBKIT_DEFINE_TYPE(WebKitColorChooserRequest, webkit_color_chooser_request, G_TYPE_OBJECT) + +static void webkitColorChooserRequestDispose(GObject* object) +{ + WebKitColorChooserRequest* request = WEBKIT_COLOR_CHOOSER_REQUEST(object); + if (!request->priv->handled) + webkit_color_chooser_request_finish(request); + + G_OBJECT_CLASS(webkit_color_chooser_request_parent_class)->dispose(object); +} + +static void webkitColorChooserRequestGetProperty(GObject* object, guint propertyID, GValue* value, GParamSpec* paramSpec) +{ + WebKitColorChooserRequest* request = WEBKIT_COLOR_CHOOSER_REQUEST(object); + + switch (propertyID) { + case PROP_RGBA: + g_value_set_boxed(value, &request->priv->rgba); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyID, paramSpec); + } +} + +static void webkitColorChooserRequestSetProperty(GObject* object, guint propertyID, const GValue* value, GParamSpec* paramSpec) +{ + WebKitColorChooserRequest* request = WEBKIT_COLOR_CHOOSER_REQUEST(object); + + switch (propertyID) { + case PROP_RGBA: + webkit_color_chooser_request_set_rgba(request, static_cast<GdkRGBA*>(g_value_get_boxed(value))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyID, paramSpec); + } +} + +static void webkit_color_chooser_request_class_init(WebKitColorChooserRequestClass* requestClass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(requestClass); + objectClass->dispose = webkitColorChooserRequestDispose; + objectClass->get_property = webkitColorChooserRequestGetProperty; + objectClass->set_property = webkitColorChooserRequestSetProperty; + + /** + * WebKitWebView:rgba: + * + * The #GdkRGBA color of the request + * + * Since: 2.8 + */ + g_object_class_install_property(objectClass, + PROP_RGBA, + g_param_spec_boxed("rgba", + _("Current RGBA color"), + _("The current RGBA color for the request"), + GDK_TYPE_RGBA, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT))); + + /** + * WebKitColorChooserRequest::finished: + * @request: the #WebKitColorChooserRequest on which the signal is emitted + * + * Emitted when the @request finishes. This signal can be emitted because the + * user completed the @request calling webkit_color_chooser_request_finish(), + * or cancelled it with webkit_color_chooser_request_cancel() or because the + * color input element is removed from the DOM. + * + * Since: 2.8 + */ + signals[FINISHED] = + g_signal_new( + "finished", + G_TYPE_FROM_CLASS(requestClass), + G_SIGNAL_RUN_LAST, + 0, 0, + nullptr, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +/** + * webkit_color_chooser_request_set_rgba: + * @request: a #WebKitFileChooserRequest + * @rgba: a pointer #GdkRGBA + * + * Sets the current #GdkRGBA color of @request + * + * Since: 2.8 + */ +void webkit_color_chooser_request_set_rgba(WebKitColorChooserRequest* request, const GdkRGBA* rgba) +{ + g_return_if_fail(WEBKIT_IS_COLOR_CHOOSER_REQUEST(request)); + g_return_if_fail(rgba); + + if (gdk_rgba_equal(&request->priv->rgba, rgba)) + return; + + request->priv->rgba = *rgba; + g_object_notify(G_OBJECT(request), "rgba"); +} + +/** + * webkit_color_chooser_request_get_rgba: + * @request: a #WebKitColorChooserRequest + * @rgba: (out): a #GdkRGBA to fill in with the current color. + * + * Gets the current #GdkRGBA color of @request + * + * Since: 2.8 + */ +void webkit_color_chooser_request_get_rgba(WebKitColorChooserRequest* request, GdkRGBA* rgba) +{ + g_return_if_fail(WEBKIT_IS_COLOR_CHOOSER_REQUEST(request)); + g_return_if_fail(rgba); + + *rgba = request->priv->rgba; +} + +/** + * webkit_color_chooser_request_get_element_rectangle: + * @request: a #WebKitColorChooserRequest + * @rect: (out): a #GdkRectangle to fill in with the element area + * + * Gets the bounding box of the color input element. + * + * Since: 2.8 + */ +void webkit_color_chooser_request_get_element_rectangle(WebKitColorChooserRequest* request, GdkRectangle* rect) +{ + g_return_if_fail(WEBKIT_IS_COLOR_CHOOSER_REQUEST(request)); + g_return_if_fail(rect); + + *rect = request->priv->colorChooser->elementRect(); +} + +/** + * webkit_color_chooser_request_finish: + * @request: a #WebKitColorChooserRequest + * + * Finishes @request and the input element keeps the current value of + * #WebKitColorChooserRequest:rgba. + * The signal #WebKitColorChooserRequest::finished + * is emitted to notify that the request has finished. + * + * Since: 2.8 + */ +void webkit_color_chooser_request_finish(WebKitColorChooserRequest* request) +{ + g_return_if_fail(WEBKIT_IS_COLOR_CHOOSER_REQUEST(request)); + + if (request->priv->handled) + return; + + request->priv->handled = true; + g_signal_emit(request, signals[FINISHED], 0); +} + +/** + * webkit_color_chooser_request_cancel: + * @request: a #WebKitColorChooserRequest + * + * Cancels @request and the input element changes to use the initial color + * it has before the request started. + * The signal #WebKitColorChooserRequest::finished + * is emitted to notify that the request has finished. + * + * Since: 2.8 + */ +void webkit_color_chooser_request_cancel(WebKitColorChooserRequest* request) +{ + g_return_if_fail(WEBKIT_IS_COLOR_CHOOSER_REQUEST(request)); + + if (request->priv->handled) + return; + + request->priv->handled = true; + request->priv->colorChooser->cancel(); + g_signal_emit(request, signals[FINISHED], 0); +} + +WebKitColorChooserRequest* webkitColorChooserRequestCreate(WebKitColorChooser* colorChooser) +{ + WebKitColorChooserRequest* request = WEBKIT_COLOR_CHOOSER_REQUEST( + g_object_new(WEBKIT_TYPE_COLOR_CHOOSER_REQUEST, "rgba", colorChooser->initialColor(), nullptr)); + request->priv->colorChooser = colorChooser; + return request; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequest.h b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequest.h new file mode 100644 index 000000000..33a4ebb35 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequest.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * Copyright (c) 2012, Samsung Electronics + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitColorChooserRequest_h +#define WebKitColorChooserRequest_h + +#include <gtk/gtk.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_COLOR_CHOOSER_REQUEST (webkit_color_chooser_request_get_type()) +#define WEBKIT_COLOR_CHOOSER_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_COLOR_CHOOSER_REQUEST, WebKitColorChooserRequest)) +#define WEBKIT_IS_COLOR_CHOOSER_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_COLOR_CHOOSER_REQUEST)) +#define WEBKIT_COLOR_CHOOSER_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_COLOR_CHOOSER_REQUEST, WebKitColorChooserRequestClass)) +#define WEBKIT_IS_COLOR_CHOOSER_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_COLOR_CHOOSER_REQUEST)) +#define WEBKIT_COLOR_CHOOSER_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_COLOR_CHOOSER_REQUEST, WebKitColorChooserRequestClass)) + +typedef struct _WebKitColorChooserRequest WebKitColorChooserRequest; +typedef struct _WebKitColorChooserRequestClass WebKitColorChooserRequestClass; +typedef struct _WebKitColorChooserRequestPrivate WebKitColorChooserRequestPrivate; + +struct _WebKitColorChooserRequest { + GObject parent; + + /*< private >*/ + WebKitColorChooserRequestPrivate *priv; +}; + +struct _WebKitColorChooserRequestClass { + GObjectClass parent_class; +}; + +WEBKIT_API GType +webkit_color_chooser_request_get_type (void); + +WEBKIT_API void +webkit_color_chooser_request_get_rgba (WebKitColorChooserRequest *request, + GdkRGBA *rgba); + +WEBKIT_API void +webkit_color_chooser_request_set_rgba (WebKitColorChooserRequest *request, + const GdkRGBA *rgba); + +WEBKIT_API void +webkit_color_chooser_request_get_element_rectangle (WebKitColorChooserRequest *request, + GdkRectangle *rect); + +WEBKIT_API void +webkit_color_chooser_request_finish (WebKitColorChooserRequest *request); + +WEBKIT_API void +webkit_color_chooser_request_cancel (WebKitColorChooserRequest *request); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequestPrivate.h new file mode 100644 index 000000000..3acfe2821 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequestPrivate.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * Copyright (c) 2012, Samsung Electronics + * + * 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. + * + * 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 WebKitColorChooserRequestPrivate_h +#define WebKitColorChooserRequestPrivate_h + +#include "WebKitColorChooser.h" +#include "WebKitColorChooserRequest.h" + +WebKitColorChooserRequest* webkitColorChooserRequestCreate(WebKit::WebKitColorChooser*); + +#endif // WebKitColorChooserRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.cpp index bbbed0ddc..ff0879648 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.cpp @@ -24,6 +24,7 @@ #include "WebContextMenuItem.h" #include "WebKitContextMenuItemPrivate.h" #include "WebKitContextMenuPrivate.h" +#include <wtf/glib/GRefPtr.h> using namespace WebKit; using namespace WebCore; @@ -50,6 +51,7 @@ using namespace WebCore; struct _WebKitContextMenuPrivate { GList* items; WebKitContextMenuItem* parentItem; + GRefPtr<GVariant> userData; }; WEBKIT_DEFINE_TYPE(WebKitContextMenu, webkit_context_menu, G_TYPE_OBJECT) @@ -66,21 +68,27 @@ static void webkit_context_menu_class_init(WebKitContextMenuClass* listClass) gObjectClass->dispose = webkitContextMenuDispose; } -void webkitContextMenuPopulate(WebKitContextMenu* menu, Vector<ContextMenuItem>& contextMenuItems) +void webkitContextMenuPopulate(WebKitContextMenu* menu, Vector<WebContextMenuItemData>& contextMenuItems) { for (GList* item = menu->priv->items; item; item = g_list_next(item)) { WebKitContextMenuItem* menuItem = WEBKIT_CONTEXT_MENU_ITEM(item->data); - contextMenuItems.append(ContextMenuItem(webkitContextMenuItemRelease(menuItem))); + contextMenuItems.append(webkitContextMenuItemToWebContextMenuItemData(menuItem)); } } -WebKitContextMenu* webkitContextMenuCreate(API::Array* items) +void webkitContextMenuPopulate(WebKitContextMenu* menu, Vector<WebContextMenuItemGtk>& contextMenuItems) +{ + for (GList* item = menu->priv->items; item; item = g_list_next(item)) { + WebKitContextMenuItem* menuItem = WEBKIT_CONTEXT_MENU_ITEM(item->data); + contextMenuItems.append(webkitContextMenuItemToWebContextMenuItemGtk(menuItem)); + } +} + +WebKitContextMenu* webkitContextMenuCreate(const Vector<WebContextMenuItemData>& items) { WebKitContextMenu* menu = webkit_context_menu_new(); - for (size_t i = 0; i < items->size(); ++i) { - WebContextMenuItem* item = static_cast<WebContextMenuItem*>(items->at(i)); + for (const auto& item : items) webkit_context_menu_prepend(menu, webkitContextMenuItemCreate(item)); - } menu->priv->items = g_list_reverse(menu->priv->items); return menu; @@ -316,3 +324,42 @@ void webkit_context_menu_remove_all(WebKitContextMenu* menu) g_list_free_full(menu->priv->items, reinterpret_cast<GDestroyNotify>(g_object_unref)); menu->priv->items = 0; } + +/** + * webkit_context_menu_set_user_data: + * @menu: a #WebKitContextMenu + * @user_data: a #GVariant + * + * Sets user data to @menu. + * This function can be used from a Web Process extension to set user data + * that can be retrieved from the UI Process using webkit_context_menu_get_user_data(). + * If the @user_data #GVariant is floating, it is consumed. + * + * Since: 2.8 + */ +void webkit_context_menu_set_user_data(WebKitContextMenu* menu, GVariant* userData) +{ + g_return_if_fail(WEBKIT_IS_CONTEXT_MENU(menu)); + g_return_if_fail(userData); + + menu->priv->userData = userData; +} + +/** + * webkit_context_menu_get_user_data: + * @menu: a #WebKitContextMenu + * + * Gets the user data of @menu. + * This function can be used from the UI Process to get user data previously set + * from the Web Process with webkit_context_menu_set_user_data(). + * + * Returns: (transfer none): the user data of @menu, or %NULL if @menu doesn't have user data + * + * Since: 2.8 + */ +GVariant* webkit_context_menu_get_user_data(WebKitContextMenu* menu) +{ + g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU(menu), nullptr); + + return menu->priv->userData.get(); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.h b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.h index 22f4bef29..9b50c6470 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.h @@ -17,7 +17,7 @@ * Boston, MA 02110-1301, USA. */ -#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__) #error "Only <webkit2/webkit2.h> can be included directly." #endif @@ -105,6 +105,13 @@ webkit_context_menu_remove (WebKitContextMenu *menu, WEBKIT_API void webkit_context_menu_remove_all (WebKitContextMenu *menu); +WEBKIT_API void +webkit_context_menu_set_user_data (WebKitContextMenu *menu, + GVariant *user_data); + +WEBKIT_API GVariant * +webkit_context_menu_get_user_data (WebKitContextMenu *menu); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.cpp index e8cdffd04..cf1ddf955 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.cpp @@ -135,9 +135,9 @@ ContextMenuAction webkitContextMenuActionGetActionTag(WebKitContextMenuAction ac return ContextMenuItemBaseApplicationTag; } -WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(ContextMenuItem* menuItem) +WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(const WebKit::WebContextMenuItemGtk& menuItem) { - switch (menuItem->action()) { + switch (menuItem.action()) { case ContextMenuItemTagNoAction: return WEBKIT_CONTEXT_MENU_ACTION_NO_ACTION; case ContextMenuItemTagOpenLink: @@ -182,6 +182,8 @@ WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(ContextMenu return WEBKIT_CONTEXT_MENU_ACTION_UNICODE; case ContextMenuItemTagSpellingGuess: return WEBKIT_CONTEXT_MENU_ACTION_SPELLING_GUESS; + case ContextMenuItemTagNoGuessesFound: + return WEBKIT_CONTEXT_MENU_ACTION_NO_GUESSES_FOUND; case ContextMenuItemTagIgnoreSpelling: return WEBKIT_CONTEXT_MENU_ACTION_IGNORE_SPELLING; case ContextMenuItemTagLearnSpelling: @@ -201,10 +203,10 @@ WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(ContextMenu case ContextMenuItemTagInspectElement: return WEBKIT_CONTEXT_MENU_ACTION_INSPECT_ELEMENT; case ContextMenuItemTagOpenMediaInNewWindow: - return menuItem->title() == contextMenuItemTagOpenVideoInNewWindow() ? + return menuItem.title() == contextMenuItemTagOpenVideoInNewWindow() ? WEBKIT_CONTEXT_MENU_ACTION_OPEN_VIDEO_IN_NEW_WINDOW : WEBKIT_CONTEXT_MENU_ACTION_OPEN_AUDIO_IN_NEW_WINDOW; case ContextMenuItemTagCopyMediaLinkToClipboard: - return menuItem->title() == contextMenuItemTagCopyVideoLinkToClipboard() ? + return menuItem.title() == contextMenuItemTagCopyVideoLinkToClipboard() ? WEBKIT_CONTEXT_MENU_ACTION_COPY_VIDEO_LINK_TO_CLIPBOARD : WEBKIT_CONTEXT_MENU_ACTION_COPY_AUDIO_LINK_TO_CLIPBOARD; case ContextMenuItemTagToggleMediaControls: return WEBKIT_CONTEXT_MENU_ACTION_TOGGLE_MEDIA_CONTROLS; @@ -213,12 +215,12 @@ WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(ContextMenu case ContextMenuItemTagEnterVideoFullscreen: return WEBKIT_CONTEXT_MENU_ACTION_ENTER_VIDEO_FULLSCREEN; case ContextMenuItemTagMediaPlayPause: - return menuItem->title() == contextMenuItemTagMediaPlay() ? + return menuItem.title() == contextMenuItemTagMediaPlay() ? WEBKIT_CONTEXT_MENU_ACTION_MEDIA_PLAY : WEBKIT_CONTEXT_MENU_ACTION_MEDIA_PAUSE; case ContextMenuItemTagMediaMute: return WEBKIT_CONTEXT_MENU_ACTION_MEDIA_MUTE; case ContextMenuItemTagDownloadMediaToDisk: - return menuItem->title() == contextMenuItemTagDownloadVideoToDisk() ? + return menuItem.title() == contextMenuItemTagDownloadVideoToDisk() ? WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_VIDEO_TO_DISK : WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_AUDIO_TO_DISK; case ContextMenuItemBaseApplicationTag: return WEBKIT_CONTEXT_MENU_ACTION_CUSTOM; diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.h b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.h index c8c9a0dad..cf155e13a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.h @@ -17,7 +17,7 @@ * Boston, MA 02110-1301, USA. */ -#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__) #error "Only <webkit2/webkit2.h> can be included directly." #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActionsPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActionsPrivate.h index f753bb97c..e00b8e2df 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActionsPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActionsPrivate.h @@ -20,12 +20,12 @@ #ifndef WebKitContextMenuActionsPrivate_h #define WebKitContextMenuActionsPrivate_h +#include "WebContextMenuItemGtk.h" #include "WebKitContextMenuActions.h" -#include <WebCore/ContextMenuItem.h> bool webkitContextMenuActionIsCheckable(WebKitContextMenuAction); WebCore::ContextMenuAction webkitContextMenuActionGetActionTag(WebKitContextMenuAction); -WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(WebCore::ContextMenuItem*); +WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(const WebKit::WebContextMenuItemGtk&); String webkitContextMenuActionGetLabel(WebKitContextMenuAction); #endif // WebKitPrintOperationPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp index ea5e42757..6671dc93a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp @@ -20,32 +20,44 @@ #include "config.h" #include "WebKitContextMenuClient.h" -#include "WebKitPrivate.h" +#include "APIContextMenuClient.h" +#include "WebContextMenuItem.h" #include "WebKitWebViewBasePrivate.h" #include "WebKitWebViewPrivate.h" using namespace WebKit; -static void getContextMenuFromProposedMenu(WKPageRef, WKArrayRef proposedMenu, WKArrayRef*, WKHitTestResultRef hitTestResult, WKTypeRef userData, const void* clientInfo) -{ - webkitWebViewPopulateContextMenu(WEBKIT_WEB_VIEW(clientInfo), toImpl(proposedMenu), toImpl(hitTestResult)); -} +class ContextMenuClient final: public API::ContextMenuClient { +public: + explicit ContextMenuClient(WebKitWebView* webView) + : m_webView(webView) + { + } + +private: + bool getContextMenuFromProposedMenu(WebPageProxy&, const Vector<RefPtr<WebContextMenuItem>>& proposedMenu, Vector<RefPtr<WebContextMenuItem>>&, const WebHitTestResultData& hitTestResultData, API::Object* userData) override + { + GRefPtr<GVariant> variant; + if (userData) { + ASSERT(userData->type() == API::Object::Type::String); + CString userDataString = static_cast<API::String*>(userData)->string().utf8(); + variant = adoptGRef(g_variant_parse(nullptr, userDataString.data(), userDataString.data() + userDataString.length(), nullptr, nullptr)); + } + + Vector<WebContextMenuItemData> menuItems; + menuItems.reserveInitialCapacity(proposedMenu.size()); + for (auto& item : proposedMenu) + menuItems.uncheckedAppend(item->data()); + webkitWebViewPopulateContextMenu(m_webView, menuItems, hitTestResultData, variant.get()); + return true; + } + + WebKitWebView* m_webView; +}; void attachContextMenuClientToView(WebKitWebView* webView) { - WKPageContextMenuClientV3 wkContextMenuClient = { - { - 3, // version - webView, // clientInfo - }, - 0, // getContextMenuFromProposedMenu_deprecatedForUseWithV0 - 0, // customContextMenuItemSelected - 0, // contextMenuDismissed - getContextMenuFromProposedMenu, - 0, // showContextMenu - 0, // hideContextMenu - }; - WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); - WKPageSetPageContextMenuClient(wkPage, &wkContextMenuClient.base); + WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)); + page->setContextMenuClient(std::make_unique<ContextMenuClient>(webView)); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.cpp index c5e4553aa..5a3a47273 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.cpp @@ -22,17 +22,16 @@ #include "APIArray.h" #include "WebContextMenuItem.h" -#include "WebContextMenuItemData.h" +#include "WebContextMenuItemGtk.h" #include "WebKitContextMenuActionsPrivate.h" #include "WebKitContextMenuItemPrivate.h" #include "WebKitContextMenuPrivate.h" #include <WebCore/ContextMenu.h> #include <WebCore/ContextMenuItem.h> #include <gtk/gtk.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/gobject/GUniquePtr.h> +#include <memory> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> using namespace WebKit; using namespace WebCore; @@ -57,13 +56,13 @@ struct _WebKitContextMenuItemPrivate { webkitContextMenuSetParentItem(subMenu.get(), 0); } - OwnPtr<ContextMenuItem> menuItem; + std::unique_ptr<WebContextMenuItemGtk> menuItem; GRefPtr<WebKitContextMenu> subMenu; }; WEBKIT_DEFINE_TYPE(WebKitContextMenuItem, webkit_context_menu_item, G_TYPE_INITIALLY_UNOWNED) -static void webkit_context_menu_item_class_init(WebKitContextMenuItemClass* itemClass) +static void webkit_context_menu_item_class_init(WebKitContextMenuItemClass*) { } @@ -85,71 +84,44 @@ static void webkitContextMenuItemSetSubMenu(WebKitContextMenuItem* item, GRefPtr return; if (item->priv->subMenu) - webkitContextMenuSetParentItem(item->priv->subMenu.get(), 0); + webkitContextMenuSetParentItem(item->priv->subMenu.get(), nullptr); item->priv->subMenu = subMenu; if (subMenu) webkitContextMenuSetParentItem(subMenu.get(), item); } -WebKitContextMenuItem* webkitContextMenuItemCreate(WebContextMenuItem* webItem) +WebKitContextMenuItem* webkitContextMenuItemCreate(const WebContextMenuItemData& itemData) { WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, NULL)); - WebContextMenuItemData* itemData = webItem->data(); - item->priv->menuItem = WTF::adoptPtr(new ContextMenuItem(itemData->type(), itemData->action(), itemData->title(), itemData->enabled(), itemData->checked())); - const Vector<WebContextMenuItemData>& subMenu = itemData->submenu(); - if (!subMenu.size()) - return item; - - Vector<RefPtr<API::Object>> subMenuItems; - subMenuItems.reserveInitialCapacity(subMenu.size()); - for (size_t i = 0; i < subMenu.size(); ++i) - subMenuItems.uncheckedAppend(WebContextMenuItem::create(subMenu[i]).get()); - webkitContextMenuItemSetSubMenu(item, adoptGRef(webkitContextMenuCreate(API::Array::create(std::move(subMenuItems)).get()))); - return item; -} - -static WebKitContextMenuItem* webkitContextMenuItemCreateForGtkItem(GtkMenuItem* menuItem) -{ - WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, NULL)); - item->priv->menuItem = WTF::adoptPtr(new ContextMenuItem(menuItem)); - webkitContextMenuItemSetSubMenuFromGtkMenu(item, GTK_MENU(gtk_menu_item_get_submenu(menuItem))); + item->priv->menuItem = std::make_unique<WebContextMenuItemGtk>(itemData); + const Vector<WebContextMenuItemData>& subMenu = itemData.submenu(); + if (!subMenu.isEmpty()) + webkitContextMenuItemSetSubMenu(item, adoptGRef(webkitContextMenuCreate(subMenu))); return item; } -void webkitContextMenuItemSetSubMenuFromGtkMenu(WebKitContextMenuItem* item, GtkMenu* subMenu) +WebContextMenuItemGtk webkitContextMenuItemToWebContextMenuItemGtk(WebKitContextMenuItem* item) { - if (!subMenu) - return; - - GUniquePtr<GList> children(gtk_container_get_children(GTK_CONTAINER(subMenu))); - if (!g_list_length(children.get())) - return; - - webkitContextMenuItemSetSubMenu(item, adoptGRef(webkit_context_menu_new())); - for (GList* listItem = children.get(); listItem; listItem = g_list_next(listItem)) { - GRefPtr<GtkWidget> widget = GTK_WIDGET(listItem->data); - if (!GTK_IS_MENU_ITEM(widget.get())) - continue; - - gtk_container_remove(GTK_CONTAINER(subMenu), widget.get()); - GtkMenuItem* menuItem = GTK_MENU_ITEM(widget.leakRef()); - g_object_force_floating(G_OBJECT(menuItem)); - webkit_context_menu_append(item->priv->subMenu.get(), webkitContextMenuItemCreateForGtkItem(menuItem)); + if (item->priv->subMenu) { + Vector<WebContextMenuItemGtk> subMenuItems; + webkitContextMenuPopulate(item->priv->subMenu.get(), subMenuItems); + return WebContextMenuItemGtk(*item->priv->menuItem, WTFMove(subMenuItems)); } + + return *item->priv->menuItem; } -GtkMenuItem* webkitContextMenuItemRelease(WebKitContextMenuItem* item) +WebContextMenuItemData webkitContextMenuItemToWebContextMenuItemData(WebKitContextMenuItem* item) { if (item->priv->subMenu) { - Vector<ContextMenuItem> subMenuItems; + Vector<WebContextMenuItemData> subMenuItems; webkitContextMenuPopulate(item->priv->subMenu.get(), subMenuItems); - ContextMenu subMenu(platformMenuDescription(subMenuItems)); - item->priv->menuItem->setSubMenu(&subMenu); + return WebContextMenuItemData(item->priv->menuItem->action(), item->priv->menuItem->title(), item->priv->menuItem->enabled(), subMenuItems); } - return item->priv->menuItem->releasePlatformDescription(); + return WebContextMenuItemData(item->priv->menuItem->type(), item->priv->menuItem->action(), item->priv->menuItem->title(), item->priv->menuItem->enabled(), item->priv->menuItem->checked()); } /** @@ -162,11 +134,10 @@ GtkMenuItem* webkitContextMenuItemRelease(WebKitContextMenuItem* item) */ WebKitContextMenuItem* webkit_context_menu_item_new(GtkAction* action) { - g_return_val_if_fail(GTK_IS_ACTION(action), 0); + g_return_val_if_fail(GTK_IS_ACTION(action), nullptr); - WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, NULL)); - item->priv->menuItem = WTF::adoptPtr(new ContextMenuItem(GTK_MENU_ITEM(gtk_action_create_menu_item(action)))); - item->priv->menuItem->setAction(ContextMenuItemBaseApplicationTag); + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, nullptr)); + item->priv->menuItem = std::make_unique<WebContextMenuItemGtk>(action); return item; } @@ -189,11 +160,11 @@ WebKitContextMenuItem* webkit_context_menu_item_new(GtkAction* action) */ WebKitContextMenuItem* webkit_context_menu_item_new_from_stock_action(WebKitContextMenuAction action) { - g_return_val_if_fail(action > WEBKIT_CONTEXT_MENU_ACTION_NO_ACTION && action < WEBKIT_CONTEXT_MENU_ACTION_CUSTOM, 0); + g_return_val_if_fail(action > WEBKIT_CONTEXT_MENU_ACTION_NO_ACTION && action < WEBKIT_CONTEXT_MENU_ACTION_CUSTOM, nullptr); - WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, NULL)); + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, nullptr)); ContextMenuItemType type = webkitContextMenuActionIsCheckable(action) ? CheckableActionType : ActionType; - item->priv->menuItem = WTF::adoptPtr(new ContextMenuItem(type, webkitContextMenuActionGetActionTag(action), webkitContextMenuActionGetLabel(action))); + item->priv->menuItem = std::make_unique<WebContextMenuItemGtk>(type, webkitContextMenuActionGetActionTag(action), webkitContextMenuActionGetLabel(action)); return item; } @@ -211,11 +182,11 @@ WebKitContextMenuItem* webkit_context_menu_item_new_from_stock_action(WebKitCont */ WebKitContextMenuItem* webkit_context_menu_item_new_from_stock_action_with_label(WebKitContextMenuAction action, const gchar* label) { - g_return_val_if_fail(action > WEBKIT_CONTEXT_MENU_ACTION_NO_ACTION && action < WEBKIT_CONTEXT_MENU_ACTION_CUSTOM, 0); + g_return_val_if_fail(action > WEBKIT_CONTEXT_MENU_ACTION_NO_ACTION && action < WEBKIT_CONTEXT_MENU_ACTION_CUSTOM, nullptr); - WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, NULL)); + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, nullptr)); ContextMenuItemType type = webkitContextMenuActionIsCheckable(action) ? CheckableActionType : ActionType; - item->priv->menuItem = WTF::adoptPtr(new ContextMenuItem(type, webkitContextMenuActionGetActionTag(action), String::fromUTF8(label))); + item->priv->menuItem = std::make_unique<WebContextMenuItemGtk>(type, webkitContextMenuActionGetActionTag(action), String::fromUTF8(label)); return item; } @@ -231,14 +202,14 @@ WebKitContextMenuItem* webkit_context_menu_item_new_from_stock_action_with_label */ WebKitContextMenuItem* webkit_context_menu_item_new_with_submenu(const gchar* label, WebKitContextMenu* submenu) { - g_return_val_if_fail(label, 0); - g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU(submenu), 0); + g_return_val_if_fail(label, nullptr); + g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU(submenu), nullptr); if (checkAndWarnIfMenuHasParentItem(submenu)) - return 0; + return nullptr; - WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, NULL)); - item->priv->menuItem = WTF::adoptPtr(new ContextMenuItem(SubmenuType, ContextMenuItemBaseApplicationTag, String::fromUTF8(label))); + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, nullptr)); + item->priv->menuItem = std::make_unique<WebContextMenuItemGtk>(ActionType, ContextMenuItemBaseApplicationTag, String::fromUTF8(label)); item->priv->subMenu = submenu; webkitContextMenuSetParentItem(submenu, item); @@ -254,8 +225,8 @@ WebKitContextMenuItem* webkit_context_menu_item_new_with_submenu(const gchar* la */ WebKitContextMenuItem* webkit_context_menu_item_new_separator(void) { - WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, NULL)); - item->priv->menuItem = WTF::adoptPtr(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String())); + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, nullptr)); + item->priv->menuItem = std::make_unique<WebContextMenuItemGtk>(SeparatorType, ContextMenuItemTagNoAction, String()); return item; } @@ -271,7 +242,7 @@ WebKitContextMenuItem* webkit_context_menu_item_new_separator(void) */ GtkAction* webkit_context_menu_item_get_action(WebKitContextMenuItem* item) { - g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU_ITEM(item), 0); + g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU_ITEM(item), nullptr); return item->priv->menuItem->gtkAction(); } @@ -291,7 +262,7 @@ WebKitContextMenuAction webkit_context_menu_item_get_stock_action(WebKitContextM { g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU_ITEM(item), WEBKIT_CONTEXT_MENU_ACTION_NO_ACTION); - return webkitContextMenuActionGetForContextMenuItem(item->priv->menuItem.get()); + return webkitContextMenuActionGetForContextMenuItem(*item->priv->menuItem); } /** diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.h b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.h index 75d60d7d6..33e31241a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.h @@ -17,7 +17,7 @@ * Boston, MA 02110-1301, USA. */ -#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__) #error "Only <webkit2/webkit2.h> can be included directly." #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItemPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItemPrivate.h index 18f8c1a87..be452fd9e 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItemPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItemPrivate.h @@ -20,11 +20,12 @@ #ifndef WebKitContextMenuItemPrivate_h #define WebKitContextMenuItemPrivate_h +#include "WebContextMenuItemGtk.h" #include "WebKitContextMenuItem.h" #include "WebKitPrivate.h" -WebKitContextMenuItem* webkitContextMenuItemCreate(WebKit::WebContextMenuItem*); -GtkMenuItem* webkitContextMenuItemRelease(WebKitContextMenuItem*); -void webkitContextMenuItemSetSubMenuFromGtkMenu(WebKitContextMenuItem*, GtkMenu*); +WebKitContextMenuItem* webkitContextMenuItemCreate(const WebKit::WebContextMenuItemData&); +WebKit::WebContextMenuItemGtk webkitContextMenuItemToWebContextMenuItemGtk(WebKitContextMenuItem*); +WebKit::WebContextMenuItemData webkitContextMenuItemToWebContextMenuItemData(WebKitContextMenuItem*); #endif // WebKitContextMenuItemPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuPrivate.h index dcfd16b21..3e4cae7b3 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuPrivate.h @@ -20,11 +20,13 @@ #ifndef WebKitContextMenuPrivate_h #define WebKitContextMenuPrivate_h +#include "WebContextMenuItemGtk.h" #include "WebKitContextMenu.h" #include "WebKitPrivate.h" -WebKitContextMenu* webkitContextMenuCreate(API::Array* items); -void webkitContextMenuPopulate(WebKitContextMenu*, Vector<WebCore::ContextMenuItem>&); +WebKitContextMenu* webkitContextMenuCreate(const Vector<WebKit::WebContextMenuItemData>&); +void webkitContextMenuPopulate(WebKitContextMenu*, Vector<WebKit::WebContextMenuItemGtk>&); +void webkitContextMenuPopulate(WebKitContextMenu*, Vector<WebKit::WebContextMenuItemData>&); void webkitContextMenuSetParentItem(WebKitContextMenu*, WebKitContextMenuItem*); WebKitContextMenuItem* webkitContextMenuGetParentItem(WebKitContextMenu*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp index 2c1ef4568..75a66ec61 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp @@ -20,12 +20,14 @@ #include "config.h" #include "WebKitCookieManager.h" -#include "APIString.h" #include "SoupCookiePersistentStorageType.h" #include "WebCookieManagerProxy.h" #include "WebKitCookieManagerPrivate.h" #include "WebKitEnumTypes.h" -#include <wtf/gobject/GRefPtr.h> +#include "WebKitWebsiteDataManagerPrivate.h" +#include "WebKitWebsiteDataPrivate.h" +#include "WebsiteDataRecord.h" +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -35,15 +37,11 @@ using namespace WebKit; * @Short_description: Defines how to handle cookies in a #WebKitWebContext * @Title: WebKitCookieManager * - * The #WebKitCookieManager defines how to handle cookies in a - * #WebKitWebContext. Get it from the context with - * webkit_web_context_get_cookie_manager(), and use it to set where to - * store cookies, with webkit_cookie_manager_set_persistent_storage(), - * to get the list of domains with cookies, with - * webkit_cookie_manager_get_domains_with_cookies(), or to set the - * acceptance policy, with webkit_cookie_manager_get_accept_policy() - * (among other actions). - * + * The WebKitCookieManager defines how to set up and handle cookies. + * You can get it from a #WebKitWebsiteDataManager with + * webkit_website_data_manager_get_cookie_manager(), and use it to set where to + * store cookies with webkit_cookie_manager_set_persistent_storage(), + * or to set the acceptance policy, with webkit_cookie_manager_get_accept_policy(). */ enum { @@ -55,22 +53,60 @@ enum { struct _WebKitCookieManagerPrivate { ~_WebKitCookieManagerPrivate() { - webCookieManager->stopObservingCookieChanges(); + auto sessionID = webkitWebsiteDataManagerGetDataStore(dataManager).websiteDataStore().sessionID(); + for (auto* processPool : webkitWebsiteDataManagerGetProcessPools(dataManager)) + processPool->supplement<WebCookieManagerProxy>()->setCookieObserverCallback(sessionID, nullptr); } - RefPtr<WebCookieManagerProxy> webCookieManager; + WebKitWebsiteDataManager* dataManager; }; static guint signals[LAST_SIGNAL] = { 0, }; WEBKIT_DEFINE_TYPE(WebKitCookieManager, webkit_cookie_manager, G_TYPE_OBJECT) -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT, SoupCookiePersistentStorageText); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE, SoupCookiePersistentStorageSQLite); +static inline SoupCookiePersistentStorageType toSoupCookiePersistentStorageType(WebKitCookiePersistentStorage kitStorage) +{ + switch (kitStorage) { + case WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT: + return SoupCookiePersistentStorageText; + case WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE: + return SoupCookiePersistentStorageSQLite; + default: + ASSERT_NOT_REACHED(); + return SoupCookiePersistentStorageText; + } +} -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS, HTTPCookieAcceptPolicyAlways); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_NEVER, HTTPCookieAcceptPolicyNever); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY, HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain); +static inline WebKitCookieAcceptPolicy toWebKitCookieAcceptPolicy(HTTPCookieAcceptPolicy httpPolicy) +{ + switch (httpPolicy) { + case HTTPCookieAcceptPolicyAlways: + return WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS; + case HTTPCookieAcceptPolicyNever: + return WEBKIT_COOKIE_POLICY_ACCEPT_NEVER; + case HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain: + return WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY; + default: + ASSERT_NOT_REACHED(); + return WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS; + } +} + +static inline HTTPCookieAcceptPolicy toHTTPCookieAcceptPolicy(WebKitCookieAcceptPolicy kitPolicy) +{ + switch (kitPolicy) { + case WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS: + return HTTPCookieAcceptPolicyAlways; + case WEBKIT_COOKIE_POLICY_ACCEPT_NEVER: + return HTTPCookieAcceptPolicyNever; + case WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY: + return HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain; + default: + ASSERT_NOT_REACHED(); + return HTTPCookieAcceptPolicyAlways; + } +} static void webkit_cookie_manager_class_init(WebKitCookieManagerClass* findClass) { @@ -91,26 +127,16 @@ static void webkit_cookie_manager_class_init(WebKitCookieManagerClass* findClass G_TYPE_NONE, 0); } -static void cookiesDidChange(WKCookieManagerRef, const void* clientInfo) -{ - g_signal_emit(WEBKIT_COOKIE_MANAGER(clientInfo), signals[CHANGED], 0); -} - -WebKitCookieManager* webkitCookieManagerCreate(WebCookieManagerProxy* webCookieManager) +WebKitCookieManager* webkitCookieManagerCreate(WebKitWebsiteDataManager* dataManager) { - WebKitCookieManager* manager = WEBKIT_COOKIE_MANAGER(g_object_new(WEBKIT_TYPE_COOKIE_MANAGER, NULL)); - manager->priv->webCookieManager = webCookieManager; - - WKCookieManagerClientV0 wkCookieManagerClient = { - { - 0, // version - manager, // clientInfo - }, - cookiesDidChange - }; - WKCookieManagerSetClient(toAPI(webCookieManager), &wkCookieManagerClient.base); - manager->priv->webCookieManager->startObservingCookieChanges(); - + WebKitCookieManager* manager = WEBKIT_COOKIE_MANAGER(g_object_new(WEBKIT_TYPE_COOKIE_MANAGER, nullptr)); + manager->priv->dataManager = dataManager; + auto sessionID = webkitWebsiteDataManagerGetDataStore(manager->priv->dataManager).websiteDataStore().sessionID(); + for (auto* processPool : webkitWebsiteDataManagerGetProcessPools(manager->priv->dataManager)) { + processPool->supplement<WebCookieManagerProxy>()->setCookieObserverCallback(sessionID, [manager] { + g_signal_emit(manager, signals[CHANGED], 0); + }); + } return manager; } @@ -125,17 +151,19 @@ WebKitCookieManager* webkitCookieManagerCreate(WebCookieManagerProxy* webCookieM * Cookies are initially read from @filename to create an initial set of cookies. * Then, non-session cookies will be written to @filename when the WebKitCookieManager::changed * signal is emitted. - * By default, @cookie_manager doesn't store the cookies persistenly, so you need to call this + * By default, @cookie_manager doesn't store the cookies persistently, so you need to call this * method to keep cookies saved across sessions. + * + * This method should never be called on a #WebKitCookieManager associated to an ephemeral #WebKitWebsiteDataManager. */ void webkit_cookie_manager_set_persistent_storage(WebKitCookieManager* manager, const char* filename, WebKitCookiePersistentStorage storage) { g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager)); g_return_if_fail(filename); + g_return_if_fail(!webkit_website_data_manager_is_ephemeral(manager->priv->dataManager)); - manager->priv->webCookieManager->stopObservingCookieChanges(); - manager->priv->webCookieManager->setCookiePersistentStorage(String::fromUTF8(filename), storage); - manager->priv->webCookieManager->startObservingCookieChanges(); + for (auto* processPool : webkitWebsiteDataManagerGetProcessPools(manager->priv->dataManager)) + processPool->supplement<WebCookieManagerProxy>()->setCookiePersistentStorage(String::fromUTF8(filename), toSoupCookiePersistentStorageType(storage)); } /** @@ -149,13 +177,14 @@ void webkit_cookie_manager_set_accept_policy(WebKitCookieManager* manager, WebKi { g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager)); - manager->priv->webCookieManager->setHTTPCookieAcceptPolicy(policy); + for (auto* processPool : webkitWebsiteDataManagerGetProcessPools(manager->priv->dataManager)) + processPool->supplement<WebCookieManagerProxy>()->setHTTPCookieAcceptPolicy(toHTTPCookieAcceptPolicy(policy)); } static void webkitCookieManagerGetAcceptPolicyCallback(WKHTTPCookieAcceptPolicy policy, WKErrorRef, void* context) { GRefPtr<GTask> task = adoptGRef(G_TASK(context)); - g_task_return_int(task.get(), policy); + g_task_return_int(task.get(), toWebKitCookieAcceptPolicy(toHTTPCookieAcceptPolicy(policy))); } /** @@ -174,8 +203,17 @@ void webkit_cookie_manager_get_accept_policy(WebKitCookieManager* manager, GCanc { g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager)); - GTask* task = g_task_new(manager, cancellable, callback, userData); - manager->priv->webCookieManager->getHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicyCallback::create(task, webkitCookieManagerGetAcceptPolicyCallback)); + GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData)); + + // The policy is the same in all process pools having the same session ID, so just ask any. + const auto& processPools = webkitWebsiteDataManagerGetProcessPools(manager->priv->dataManager); + if (processPools.isEmpty()) { + g_task_return_int(task.get(), WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY); + return; + } + + processPools[0]->supplement<WebCookieManagerProxy>()->getHTTPCookieAcceptPolicy( + toGenericCallbackFunction<WKHTTPCookieAcceptPolicy, HTTPCookieAcceptPolicy>(task.leakRef(), webkitCookieManagerGetAcceptPolicyCallback)); } /** @@ -197,25 +235,6 @@ WebKitCookieAcceptPolicy webkit_cookie_manager_get_accept_policy_finish(WebKitCo return returnValue == -1 ? WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY : static_cast<WebKitCookieAcceptPolicy>(returnValue); } -static void webkitCookieManagerGetDomainsWithCookiesCallback(WKArrayRef wkDomains, WKErrorRef, void* context) -{ - GRefPtr<GTask> task = adoptGRef(G_TASK(context)); - if (g_task_return_error_if_cancelled(task.get())) - return; - - API::Array* domains = toImpl(wkDomains); - GPtrArray* returnValue = g_ptr_array_sized_new(domains->size()); - for (size_t i = 0; i < domains->size(); ++i) { - API::String* domainString = static_cast<API::String*>(domains->at(i)); - String domain = domainString->string(); - if (domain.isEmpty()) - continue; - g_ptr_array_add(returnValue, g_strdup(domain.utf8().data())); - } - g_ptr_array_add(returnValue, 0); - g_task_return_pointer(task.get(), g_ptr_array_free(returnValue, FALSE), reinterpret_cast<GDestroyNotify>(g_strfreev)); -} - /** * webkit_cookie_manager_get_domains_with_cookies: * @cookie_manager: a #WebKitCookieManager @@ -227,13 +246,32 @@ static void webkitCookieManagerGetDomainsWithCookiesCallback(WKArrayRef wkDomain * * When the operation is finished, @callback will be called. You can then call * webkit_cookie_manager_get_domains_with_cookies_finish() to get the result of the operation. + * + * Deprecated: 2.16: Use webkit_website_data_manager_fetch() instead. */ void webkit_cookie_manager_get_domains_with_cookies(WebKitCookieManager* manager, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData) { g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager)); GTask* task = g_task_new(manager, cancellable, callback, userData); - manager->priv->webCookieManager->getHostnamesWithCookies(ArrayCallback::create(task, webkitCookieManagerGetDomainsWithCookiesCallback)); + webkit_website_data_manager_fetch(manager->priv->dataManager, WEBKIT_WEBSITE_DATA_COOKIES, cancellable, [](GObject* object, GAsyncResult* result, gpointer userData) { + GRefPtr<GTask> task = adoptGRef(G_TASK(userData)); + GError* error = nullptr; + GUniquePtr<GList> dataList(webkit_website_data_manager_fetch_finish(WEBKIT_WEBSITE_DATA_MANAGER(object), result, &error)); + if (error) { + g_task_return_error(task.get(), error); + return; + } + + GPtrArray* domains = g_ptr_array_sized_new(g_list_length(dataList.get())); + for (GList* item = dataList.get(); item; item = g_list_next(item)) { + auto* data = static_cast<WebKitWebsiteData*>(item->data); + g_ptr_array_add(domains, g_strdup(webkit_website_data_get_name(data))); + webkit_website_data_unref(data); + } + g_ptr_array_add(domains, nullptr); + g_task_return_pointer(task.get(), g_ptr_array_free(domains, FALSE), reinterpret_cast<GDestroyNotify>(g_strfreev)); + }, task); } /** @@ -248,11 +286,13 @@ void webkit_cookie_manager_get_domains_with_cookies(WebKitCookieManager* manager * * Returns: (transfer full) (array zero-terminated=1): A %NULL terminated array of domain names * or %NULL in case of error. + * + * Deprecated: 2.16: Use webkit_website_data_manager_fetch_finish() instead. */ gchar** webkit_cookie_manager_get_domains_with_cookies_finish(WebKitCookieManager* manager, GAsyncResult* result, GError** error) { - g_return_val_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager), 0); - g_return_val_if_fail(g_task_is_valid(result, manager), 0); + g_return_val_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager), nullptr); + g_return_val_if_fail(g_task_is_valid(result, manager), nullptr); return reinterpret_cast<char**>(g_task_propagate_pointer(G_TASK(result), error)); } @@ -263,13 +303,20 @@ gchar** webkit_cookie_manager_get_domains_with_cookies_finish(WebKitCookieManage * @domain: a domain name * * Remove all cookies of @cookie_manager for the given @domain. + * + * Deprecated: 2.16: Use webkit_website_data_manager_remove() instead. */ void webkit_cookie_manager_delete_cookies_for_domain(WebKitCookieManager* manager, const gchar* domain) { g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager)); g_return_if_fail(domain); - manager->priv->webCookieManager->deleteCookiesForHostname(String::fromUTF8(domain)); + WebsiteDataRecord record; + record.addCookieHostName(String::fromUTF8(domain)); + auto* data = webkitWebsiteDataCreate(WTFMove(record)); + GList dataList = { data, nullptr, nullptr }; + webkit_website_data_manager_remove(manager->priv->dataManager, WEBKIT_WEBSITE_DATA_COOKIES, &dataList, nullptr, nullptr, nullptr); + webkit_website_data_unref(data); } /** @@ -277,10 +324,12 @@ void webkit_cookie_manager_delete_cookies_for_domain(WebKitCookieManager* manage * @cookie_manager: a #WebKitCookieManager * * Delete all cookies of @cookie_manager + * + * Deprecated: 2.16: Use webkit_website_data_manager_clear() instead. */ void webkit_cookie_manager_delete_all_cookies(WebKitCookieManager* manager) { g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager)); - manager->priv->webCookieManager->deleteAllCookies(); + webkit_website_data_manager_clear(manager->priv->dataManager, WEBKIT_WEBSITE_DATA_COOKIES, 0, nullptr, nullptr, nullptr); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h index f25f1a2b0..ee17d2204 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h @@ -107,22 +107,22 @@ webkit_cookie_manager_get_accept_policy_finish (WebKitCookieManager GAsyncResult *result, GError **error); -WEBKIT_API void +WEBKIT_DEPRECATED_FOR(webkit_website_data_manager_fetch) void webkit_cookie_manager_get_domains_with_cookies (WebKitCookieManager *cookie_manager, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); -WEBKIT_API gchar ** +WEBKIT_DEPRECATED_FOR(webkit_website_data_manager_fetch_finish) gchar ** webkit_cookie_manager_get_domains_with_cookies_finish (WebKitCookieManager *cookie_manager, GAsyncResult *result, GError **error); -WEBKIT_API void +WEBKIT_DEPRECATED_FOR(webkit_website_data_manager_remove) void webkit_cookie_manager_delete_cookies_for_domain (WebKitCookieManager *cookie_manager, const gchar *domain); -WEBKIT_API void +WEBKIT_DEPRECATED_FOR(webkit_website_data_manager_clear) void webkit_cookie_manager_delete_all_cookies (WebKitCookieManager *cookie_manager); G_END_DECLS diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h index 6be84afae..75ac6f287 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h @@ -17,12 +17,9 @@ * Boston, MA 02110-1301, USA. */ -#ifndef WebKitCookieManagerPrivate_h -#define WebKitCookieManagerPrivate_h +#pragma once -#include "WebKitCookieManager.h" #include "WebKitPrivate.h" +#include "WebKitWebsiteDataManager.h" -WebKitCookieManager* webkitCookieManagerCreate(WebKit::WebCookieManagerProxy*); - -#endif // WebKitCookieManagerPrivate_h +WebKitCookieManager* webkitCookieManagerCreate(WebKitWebsiteDataManager*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCredential.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitCredential.cpp index 5755fd5c7..a23e7e84b 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitCredential.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCredential.cpp @@ -37,15 +37,41 @@ struct _WebKitCredential { CString password; }; -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_CREDENTIAL_PERSISTENCE_NONE, WebCore::CredentialPersistenceNone); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_CREDENTIAL_PERSISTENCE_FOR_SESSION, WebCore::CredentialPersistenceForSession); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_CREDENTIAL_PERSISTENCE_PERMANENT, WebCore::CredentialPersistencePermanent); - G_DEFINE_BOXED_TYPE(WebKitCredential, webkit_credential, webkit_credential_copy, webkit_credential_free) +static inline WebKitCredentialPersistence toWebKitCredentialPersistence(WebCore::CredentialPersistence corePersistence) +{ + switch (corePersistence) { + case WebCore::CredentialPersistenceNone: + return WEBKIT_CREDENTIAL_PERSISTENCE_NONE; + case WebCore::CredentialPersistenceForSession: + return WEBKIT_CREDENTIAL_PERSISTENCE_FOR_SESSION; + case WebCore::CredentialPersistencePermanent: + return WEBKIT_CREDENTIAL_PERSISTENCE_PERMANENT; + default: + ASSERT_NOT_REACHED(); + return WEBKIT_CREDENTIAL_PERSISTENCE_NONE; + } +} + +static inline WebCore::CredentialPersistence toWebCoreCredentialPersistence(WebKitCredentialPersistence kitPersistence) +{ + switch (kitPersistence) { + case WEBKIT_CREDENTIAL_PERSISTENCE_NONE: + return WebCore::CredentialPersistenceNone; + case WEBKIT_CREDENTIAL_PERSISTENCE_FOR_SESSION: + return WebCore::CredentialPersistenceForSession; + case WEBKIT_CREDENTIAL_PERSISTENCE_PERMANENT: + return WebCore::CredentialPersistencePermanent; + default: + ASSERT_NOT_REACHED(); + return WebCore::CredentialPersistenceNone; + } +} + WebKitCredential* webkitCredentialCreate(const WebCore::Credential& coreCredential) { - WebKitCredential* credential = g_slice_new(WebKitCredential); + WebKitCredential* credential = static_cast<WebKitCredential*>(fastMalloc(sizeof(WebKitCredential))); new (credential) WebKitCredential(coreCredential); return credential; } @@ -73,7 +99,7 @@ WebKitCredential* webkit_credential_new(const gchar* username, const gchar* pass g_return_val_if_fail(username, 0); g_return_val_if_fail(password, 0); - return webkitCredentialCreate(WebCore::Credential(String::fromUTF8(username), String::fromUTF8(password), static_cast<WebCore::CredentialPersistence>(persistence))); + return webkitCredentialCreate(WebCore::Credential(String::fromUTF8(username), String::fromUTF8(password), toWebCoreCredentialPersistence(persistence))); } /** @@ -106,7 +132,7 @@ void webkit_credential_free(WebKitCredential* credential) g_return_if_fail(credential); credential->~WebKitCredential(); - g_slice_free(WebKitCredential, credential); + fastFree(credential); } /** @@ -178,5 +204,5 @@ WebKitCredentialPersistence webkit_credential_get_persistence(WebKitCredential* { g_return_val_if_fail(credential, WEBKIT_CREDENTIAL_PERSISTENCE_NONE); - return static_cast<WebKitCredentialPersistence>(credential->credential.persistence()); + return toWebKitCredentialPersistence(credential->credential.persistence()); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCustomProtocolManagerClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitCustomProtocolManagerClient.cpp new file mode 100644 index 000000000..f04b726f1 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCustomProtocolManagerClient.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitCustomProtocolManagerClient.h" + +#include "APICustomProtocolManagerClient.h" +#include "CustomProtocolManagerProxy.h" +#include "WebKitWebContextPrivate.h" +#include "WebProcessPool.h" + +using namespace WebCore; +using namespace WebKit; + +class CustomProtocolManagerClient final : public API::CustomProtocolManagerClient { +public: + explicit CustomProtocolManagerClient(WebKitWebContext* webContext) + : m_webContext(webContext) + { + } + +private: + void startLoading(CustomProtocolManagerProxy& manager, uint64_t customProtocolID, const ResourceRequest& request) override + { + webkitWebContextStartLoadingCustomProtocol(m_webContext, customProtocolID, request, manager); + } + + void stopLoading(CustomProtocolManagerProxy&, uint64_t customProtocolID) override + { + webkitWebContextStopLoadingCustomProtocol(m_webContext, customProtocolID); + } + + void invalidate(CustomProtocolManagerProxy& manager) override + { + webkitWebContextInvalidateCustomProtocolRequests(m_webContext, manager); + } + + WebKitWebContext* m_webContext; +}; + +void attachCustomProtocolManagerClientToContext(WebKitWebContext* webContext) +{ + webkitWebContextGetProcessPool(webContext).setCustomProtocolManagerClient(std::make_unique<CustomProtocolManagerClient>(webContext)); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.h b/Source/WebKit2/UIProcess/API/gtk/WebKitCustomProtocolManagerClient.h index a365594f8..c9c4c17cc 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCustomProtocolManagerClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Igalia S.L. + * Copyright (C) 2016 Igalia S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,11 +17,9 @@ * Boston, MA 02110-1301, USA. */ -#ifndef WebKitRequestManagerClient_h -#define WebKitRequestManagerClient_h +#pragma once #include "WebKitWebContext.h" -void attachRequestManagerClientToContext(WebKitWebContext*); +void attachCustomProtocolManagerClientToContext(WebKitWebContext*); -#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h b/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h index 8b637652b..520e9957c 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h @@ -38,10 +38,11 @@ # else # define WEBKIT_API __declspec(dllimport) # endif -# define WEBKIT_OBSOLETE_API WEBKIT_API #else # define WEBKIT_API __attribute__((visibility("default"))) -# define WEBKIT_OBSOLETE_API WEBKIT_API __attribute__((deprecated)) #endif +#define WEBKIT_DEPRECATED WEBKIT_API G_DEPRECATED +#define WEBKIT_DEPRECATED_FOR(f) WEBKIT_API G_DEPRECATED_FOR(f) + #endif // WebKitDefines_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp index e95e4c065..4fe6cb984 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Igalia S.L. + * Copyright (C) 2012, 2014 Igalia S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -23,13 +23,15 @@ #include "DownloadProxy.h" #include "WebKitDownloadPrivate.h" #include "WebKitMarshal.h" +#include "WebKitPrivate.h" #include "WebKitURIRequestPrivate.h" #include "WebKitURIResponsePrivate.h" #include <WebCore/ErrorsGtk.h> #include <WebCore/ResourceResponse.h> #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> +#include <wtf/text/CString.h> using namespace WebKit; using namespace WebCore; @@ -62,7 +64,8 @@ enum { PROP_DESTINATION, PROP_RESPONSE, - PROP_ESTIMATED_PROGRESS + PROP_ESTIMATED_PROGRESS, + PROP_ALLOW_OVERWRITE }; struct _WebKitDownloadPrivate { @@ -83,12 +86,26 @@ struct _WebKitDownloadPrivate { GUniquePtr<GTimer> timer; gdouble lastProgress; gdouble lastElapsed; + bool allowOverwrite; }; static guint signals[LAST_SIGNAL] = { 0, }; WEBKIT_DEFINE_TYPE(WebKitDownload, webkit_download, G_TYPE_OBJECT) +static void webkitDownloadSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) +{ + WebKitDownload* download = WEBKIT_DOWNLOAD(object); + + switch (propId) { + case PROP_ALLOW_OVERWRITE: + webkit_download_set_allow_overwrite(download, g_value_get_boolean(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + static void webkitDownloadGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) { WebKitDownload* download = WEBKIT_DOWNLOAD(object); @@ -103,6 +120,9 @@ static void webkitDownloadGetProperty(GObject* object, guint propId, GValue* val case PROP_ESTIMATED_PROGRESS: g_value_set_double(value, webkit_download_get_estimated_progress(download)); break; + case PROP_ALLOW_OVERWRITE: + g_value_set_boolean(value, webkit_download_get_allow_overwrite(download)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); } @@ -129,6 +149,7 @@ static gboolean webkitDownloadDecideDestination(WebKitDownload* download, const static void webkit_download_class_init(WebKitDownloadClass* downloadClass) { GObjectClass* objectClass = G_OBJECT_CLASS(downloadClass); + objectClass->set_property = webkitDownloadSetProperty; objectClass->get_property = webkitDownloadGetProperty; downloadClass->decide_destination = webkitDownloadDecideDestination; @@ -178,6 +199,25 @@ static void webkit_download_class_init(WebKitDownloadClass* downloadClass) WEBKIT_PARAM_READABLE)); /** + * WebKitDownload:allow-overwrite: + * + * Whether or not the download is allowed to overwrite an existing file on + * disk. If this property is %FALSE and the destination already exists, + * the download will fail. + * + * Since: 2.6 + */ + g_object_class_install_property( + objectClass, + PROP_ALLOW_OVERWRITE, + g_param_spec_boolean( + "allow-overwrite", + _("Allow Overwrite"), + _("Whether the destination may be overwritten"), + FALSE, + WEBKIT_PARAM_READWRITE)); + + /** * WebKitDownload::received-data: * @download: the #WebKitDownload * @data_length: the length of data received in bytes @@ -223,13 +263,14 @@ static void webkit_download_class_init(WebKitDownloadClass* downloadClass) * after an error and #WebKitDownload::finished signal is emitted after this one. */ signals[FAILED] = - g_signal_new("failed", - G_TYPE_FROM_CLASS(objectClass), - G_SIGNAL_RUN_LAST, - 0, 0, 0, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); + g_signal_new( + "failed", + G_TYPE_FROM_CLASS(objectClass), + G_SIGNAL_RUN_LAST, + 0, 0, 0, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + G_TYPE_ERROR | G_SIGNAL_TYPE_STATIC_SCOPE); /** * WebKitDownload::decide-destination: @@ -282,13 +323,6 @@ WebKitDownload* webkitDownloadCreate(DownloadProxy* downloadProxy) return download; } -WebKitDownload* webkitDownloadCreateForRequest(DownloadProxy* downloadProxy, const ResourceRequest& request) -{ - WebKitDownload* download = webkitDownloadCreate(downloadProxy); - download->priv->request = adoptGRef(webkitURIRequestCreateForResourceRequest(request)); - return download; -} - void webkitDownloadSetResponse(WebKitDownload* download, WebKitURIResponse* response) { download->priv->response = response; @@ -340,7 +374,7 @@ void webkitDownloadNotifyProgress(WebKitDownload* download, guint64 bytesReceive void webkitDownloadFailed(WebKitDownload* download, const ResourceError& resourceError) { GUniquePtr<GError> webError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()), - resourceError.errorCode(), resourceError.localizedDescription().utf8().data())); + toWebKitError(resourceError.errorCode()), resourceError.localizedDescription().utf8().data())); if (download->priv->timer) g_timer_stop(download->priv->timer.get()); @@ -369,20 +403,26 @@ void webkitDownloadFinished(WebKitDownload* download) g_signal_emit(download, signals[FINISHED], 0, NULL); } -CString webkitDownloadDecideDestinationWithSuggestedFilename(WebKitDownload* download, const CString& suggestedFilename) +String webkitDownloadDecideDestinationWithSuggestedFilename(WebKitDownload* download, const CString& suggestedFilename, bool& allowOverwrite) { if (download->priv->isCancelled) - return ""; + return emptyString(); gboolean returnValue; g_signal_emit(download, signals[DECIDE_DESTINATION], 0, suggestedFilename.data(), &returnValue); - return download->priv->destinationURI; + allowOverwrite = download->priv->allowOverwrite; + GUniquePtr<char> destinationPath(g_filename_from_uri(download->priv->destinationURI.data(), nullptr, nullptr)); + if (!destinationPath) + return emptyString(); + return String::fromUTF8(destinationPath.get()); } -void webkitDownloadDestinationCreated(WebKitDownload* download, const CString& destinationURI) +void webkitDownloadDestinationCreated(WebKitDownload* download, const String& destinationPath) { if (download->priv->isCancelled) return; - g_signal_emit(download, signals[CREATED_DESTINATION], 0, destinationURI.data(), nullptr); + GUniquePtr<char> destinationURI(g_filename_to_uri(destinationPath.utf8().data(), nullptr, nullptr)); + ASSERT(destinationURI); + g_signal_emit(download, signals[CREATED_DESTINATION], 0, destinationURI.get()); } /** @@ -567,3 +607,44 @@ WebKitWebView* webkit_download_get_web_view(WebKitDownload* download) return download->priv->webView; } + +/** + * webkit_download_get_allow_overwrite: + * @download: a #WebKitDownload + * + * Returns the current value of the #WebKitDownload:allow-overwrite property, + * which determines whether the download will overwrite an existing file on + * disk, or if it will fail if the destination already exists. + * + * Returns: the current value of the #WebKitDownload:allow-overwrite property + * + * Since: 2.6 + */ +gboolean webkit_download_get_allow_overwrite(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), FALSE); + + return download->priv->allowOverwrite; +} + +/** + * webkit_download_set_allow_overwrite: + * @download: a #WebKitDownload + * @allowed: the new value for the #WebKitDownload:allow-overwrite property + * + * Sets the #WebKitDownload:allow-overwrite property, which determines whether + * the download may overwrite an existing file on disk, or if it will fail if + * the destination already exists. + * + * Since: 2.6 + */ +void webkit_download_set_allow_overwrite(WebKitDownload* download, gboolean allowed) +{ + g_return_if_fail(WEBKIT_IS_DOWNLOAD(download)); + + if (allowed == download->priv->allowOverwrite) + return; + + download->priv->allowOverwrite = allowed; + g_object_notify(G_OBJECT(download), "allow-overwrite"); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h index 493bfea40..7e6bfeb46 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h @@ -92,6 +92,13 @@ webkit_download_get_received_data_length (WebKitDownload *download); WEBKIT_API WebKitWebView * webkit_download_get_web_view (WebKitDownload *download); +WEBKIT_API gboolean +webkit_download_get_allow_overwrite (WebKitDownload *download); + +WEBKIT_API void +webkit_download_set_allow_overwrite (WebKitDownload *download, + gboolean allowed); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadClient.cpp index 198cc68f9..f4e13b9e2 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadClient.cpp @@ -20,98 +20,101 @@ #include "config.h" #include "WebKitDownloadClient.h" -#include "APIURLResponse.h" -#include "WebContext.h" +#include "APIDownloadClient.h" #include "WebKitDownloadPrivate.h" #include "WebKitURIResponsePrivate.h" #include "WebKitWebContextPrivate.h" -#include <WebKit2/WKString.h> -#include <wtf/gobject/GRefPtr.h> +#include "WebKitWebViewPrivate.h" +#include "WebProcessPool.h" +#include <WebKit/WKString.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebCore; using namespace WebKit; -static void didStart(WKContextRef, WKDownloadRef wkDownload, const void* clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - webkitWebContextDownloadStarted(WEBKIT_WEB_CONTEXT(clientInfo), download.get()); -} +class DownloadClient final : public API::DownloadClient { +public: + explicit DownloadClient(WebKitWebContext* webContext) + : m_webContext(webContext) + { + } -static void didReceiveResponse(WKContextRef, WKDownloadRef wkDownload, WKURLResponseRef wkResponse, const void* clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - if (webkitDownloadIsCancelled(download.get())) - return; +private: + void didStart(WebProcessPool*, DownloadProxy* downloadProxy) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + webkitWebContextDownloadStarted(m_webContext, download.get()); + } - GRefPtr<WebKitURIResponse> response = adoptGRef(webkitURIResponseCreateForResourceResponse(toImpl(wkResponse)->resourceResponse())); - webkitDownloadSetResponse(download.get(), response.get()); -} + void didReceiveAuthenticationChallenge(WebProcessPool*, DownloadProxy* downloadProxy, AuthenticationChallengeProxy* authenticationChallenge) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + if (webkitDownloadIsCancelled(download.get())) + return; -static void didReceiveData(WKContextRef, WKDownloadRef wkDownload, uint64_t length, const void* clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - webkitDownloadNotifyProgress(download.get(), length); -} + // FIXME: Add API to handle authentication of downloads without a web view associted. + if (auto* webView = webkit_download_get_web_view(download.get())) + webkitWebViewHandleAuthenticationChallenge(webView, authenticationChallenge); + } -static WKStringRef decideDestinationWithSuggestedFilename(WKContextRef, WKDownloadRef wkDownload, WKStringRef filename, bool* allowOverwrite, const void* clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - CString destinationURI = webkitDownloadDecideDestinationWithSuggestedFilename(download.get(), - toImpl(filename)->string().utf8()); - return WKStringCreateWithUTF8CString(destinationURI.data()); -} + void didReceiveResponse(WebProcessPool*, DownloadProxy* downloadProxy, const ResourceResponse& resourceResponse) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + if (webkitDownloadIsCancelled(download.get())) + return; -static void didCreateDestination(WKContextRef, WKDownloadRef wkDownload, WKStringRef path, const void* clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - webkitDownloadDestinationCreated(download.get(), toImpl(path)->string().utf8()); -} + GRefPtr<WebKitURIResponse> response = adoptGRef(webkitURIResponseCreateForResourceResponse(resourceResponse)); + webkitDownloadSetResponse(download.get(), response.get()); + } -static void didFail(WKContextRef, WKDownloadRef wkDownload, WKErrorRef error, const void *clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - if (webkitDownloadIsCancelled(download.get())) { - // Cancellation takes precedence over other errors. + void didReceiveData(WebProcessPool*, DownloadProxy* downloadProxy, uint64_t length) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + webkitDownloadNotifyProgress(download.get(), length); + } + + String decideDestinationWithSuggestedFilename(WebProcessPool*, DownloadProxy* downloadProxy, const String& filename, bool& allowOverwrite) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + return webkitDownloadDecideDestinationWithSuggestedFilename(download.get(), filename.utf8(), allowOverwrite); + } + + void didCreateDestination(WebProcessPool*, DownloadProxy* downloadProxy, const String& path) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + webkitDownloadDestinationCreated(download.get(), path); + } + + void didFail(WebProcessPool*, DownloadProxy* downloadProxy, const ResourceError& error) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + if (webkitDownloadIsCancelled(download.get())) { + // Cancellation takes precedence over other errors. + webkitDownloadCancelled(download.get()); + } else + webkitDownloadFailed(download.get(), error); + webkitWebContextRemoveDownload(downloadProxy); + } + + void didCancel(WebProcessPool*, DownloadProxy* downloadProxy) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); webkitDownloadCancelled(download.get()); - } else - webkitDownloadFailed(download.get(), toImpl(error)->platformError()); - webkitWebContextRemoveDownload(toImpl(wkDownload)); -} + webkitWebContextRemoveDownload(downloadProxy); + } -static void didCancel(WKContextRef, WKDownloadRef wkDownload, const void *clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - webkitDownloadCancelled(download.get()); - webkitWebContextRemoveDownload(toImpl(wkDownload)); -} + void didFinish(WebProcessPool*, DownloadProxy* downloadProxy) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + webkitDownloadFinished(download.get()); + webkitWebContextRemoveDownload(downloadProxy); + } -static void didFinish(WKContextRef wkContext, WKDownloadRef wkDownload, const void *clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - webkitDownloadFinished(download.get()); - webkitWebContextRemoveDownload(toImpl(wkDownload)); -} + WebKitWebContext* m_webContext; +}; void attachDownloadClientToContext(WebKitWebContext* webContext) { - WKContextDownloadClientV0 wkDownloadClient = { - { - 0, // version - webContext, // ClientInfo - }, - didStart, - 0, // didReceiveAuthenticationChallenge - didReceiveResponse, - didReceiveData, - 0, // shouldDecodeSourceDataOfMIMEType - decideDestinationWithSuggestedFilename, - didCreateDestination, - didFinish, - didFail, - didCancel, - 0, // processDidCrash - }; - WKContextSetDownloadClient(toAPI(webkitWebContextGetContext(webContext)), &wkDownloadClient.base); + webkitWebContextGetProcessPool(webContext).setDownloadClient(std::make_unique<DownloadClient>(webContext)); } - diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadPrivate.h index 980ad732b..2d925de9c 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadPrivate.h @@ -24,10 +24,8 @@ #include "WebKitPrivate.h" #include <WebCore/ResourceError.h> #include <WebCore/ResourceRequest.h> -#include <wtf/text/CString.h> WebKitDownload* webkitDownloadCreate(WebKit::DownloadProxy*); -WebKitDownload* webkitDownloadCreateForRequest(WebKit::DownloadProxy*, const WebCore::ResourceRequest&); bool webkitDownloadIsCancelled(WebKitDownload*); void webkitDownloadSetResponse(WebKitDownload*, WebKitURIResponse*); void webkitDownloadSetWebView(WebKitDownload*, WebKitWebView*); @@ -35,7 +33,7 @@ void webkitDownloadNotifyProgress(WebKitDownload*, guint64 bytesReceived); void webkitDownloadFailed(WebKitDownload*, const WebCore::ResourceError&); void webkitDownloadCancelled(WebKitDownload*); void webkitDownloadFinished(WebKitDownload*); -CString webkitDownloadDecideDestinationWithSuggestedFilename(WebKitDownload*, const CString& suggestedFilename); -void webkitDownloadDestinationCreated(WebKitDownload*, const CString& destinationURI); +String webkitDownloadDecideDestinationWithSuggestedFilename(WebKitDownload*, const CString& suggestedFilename, bool& allowOverwrite); +void webkitDownloadDestinationCreated(WebKitDownload*, const String& destinationPath); #endif // WebKitDownloadPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitEditingCommands.h b/Source/WebKit2/UIProcess/API/gtk/WebKitEditingCommands.h index 437395710..f6a2061ca 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitEditingCommands.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitEditingCommands.h @@ -94,6 +94,31 @@ G_BEGIN_DECLS */ #define WEBKIT_EDITING_COMMAND_REDO "Redo" +/** + * WEBKIT_EDITING_COMMAND_INSERT_IMAGE: + * + * The insert image command. Creates an image element that is inserted at + * the current cursor position. It receives an URI as argument, + * that is used as the image source. This command should be executed with + * webkit_web_view_execute_editing_command_with_argument(). + * + * Since: 2.10 + */ +#define WEBKIT_EDITING_COMMAND_INSERT_IMAGE "InsertImage" + +/** + * WEBKIT_EDITING_COMMAND_CREATE_LINK: + * + * The create link command. Creates a link element that is inserted at + * the current cursor position. If there's a selection, the selected text + * will be used as the link text, otherwise the URL itself will be used. + * It receives the link URL as argument. This command should be executed + * with webkit_web_view_execute_editing_command_with_argument() + * + * Since: 2.10 + */ +#define WEBKIT_EDITING_COMMAND_CREATE_LINK "CreateLink" + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.cpp new file mode 100644 index 000000000..97d1f8a17 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitEditorState.h" + +#include "EditorState.h" +#include "WebKitEditorStatePrivate.h" +#include <glib/gi18n-lib.h> + +using namespace WebKit; + +/** + * SECTION: WebKitEditorState + * @Short_description: Web editor state + * @Title: WebKitEditorState + * @See_also: #WebKitWebView + * + * WebKitEditorState represents the state of a #WebKitWebView editor. + * Use webkit_web_view_get_editor_state() to get WebKitEditorState of + * a #WebKitWebView. + * + * Since: 2.10 + */ + +enum { + PROP_0, + + PROP_TYPING_ATTRIBUTES +}; + +struct _WebKitEditorStatePrivate { + unsigned typingAttributes; +}; + +WEBKIT_DEFINE_TYPE(WebKitEditorState, webkit_editor_state, G_TYPE_OBJECT) + +static void webkitEditorStateGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) +{ + WebKitEditorState* editorState = WEBKIT_EDITOR_STATE(object); + + switch (propId) { + case PROP_TYPING_ATTRIBUTES: + g_value_set_uint(value, webkit_editor_state_get_typing_attributes(editorState)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkit_editor_state_class_init(WebKitEditorStateClass* editorStateClass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(editorStateClass); + objectClass->get_property = webkitEditorStateGetProperty; + + /** + * WebKitEditorState:typing-attributes: + * + * Bitmask of #WebKitEditorTypingAttributes flags. + * See webkit_editor_state_get_typing_attributes() for more information. + * + * Since: 2.10 + */ + g_object_class_install_property( + objectClass, + PROP_TYPING_ATTRIBUTES, + g_param_spec_uint( + "typing-attributes", + _("Typing Attributes"), + _("Flags with the typing attributes"), + 0, G_MAXUINT, 0, + WEBKIT_PARAM_READABLE)); +} + +static void webkitEditorStateSetTypingAttributes(WebKitEditorState* editorState, unsigned typingAttributes) +{ + if (typingAttributes == editorState->priv->typingAttributes) + return; + + editorState->priv->typingAttributes = typingAttributes; + g_object_notify(G_OBJECT(editorState), "typing-attributes"); +} + +WebKitEditorState* webkitEditorStateCreate(const EditorState& state) +{ + WebKitEditorState* editorState = WEBKIT_EDITOR_STATE(g_object_new(WEBKIT_TYPE_EDITOR_STATE, nullptr)); + webkitEditorStateChanged(editorState, state); + return editorState; +} + +void webkitEditorStateChanged(WebKitEditorState* editorState, const EditorState& newState) +{ + if (newState.isMissingPostLayoutData) + return; + + unsigned typingAttributes = WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE; + const auto& postLayoutData = newState.postLayoutData(); + if (postLayoutData.typingAttributes & AttributeBold) + typingAttributes |= WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD; + if (postLayoutData.typingAttributes & AttributeItalics) + typingAttributes |= WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC; + if (postLayoutData.typingAttributes & AttributeUnderline) + typingAttributes |= WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE; + if (postLayoutData.typingAttributes & AttributeStrikeThrough) + typingAttributes |= WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH; + webkitEditorStateSetTypingAttributes(editorState, typingAttributes); +} + +/** + * webkit_editor_state_get_typing_attributes: + * @editor_state: a #WebKitEditorState + * + * Gets the typing attributes at the current cursor position. + * If there is a selection, this returns the typing attributes + * of the the selected text. Note that in case of a selection, + * typing attributes are considered active only when they are + * present throughout the selection. + * + * Returns: a bitmask of #WebKitEditorTypingAttributes flags + * + * Since: 2.10 + */ +guint webkit_editor_state_get_typing_attributes(WebKitEditorState* editorState) +{ + g_return_val_if_fail(WEBKIT_IS_EDITOR_STATE(editorState), WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE); + + return editorState->priv->typingAttributes; +} + diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.h b/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.h new file mode 100644 index 000000000..ae644a90a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitEditorState_h +#define WebKitEditorState_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_EDITOR_STATE (webkit_editor_state_get_type()) +#define WEBKIT_EDITOR_STATE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_EDITOR_STATE, WebKitEditorState)) +#define WEBKIT_IS_EDITOR_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_EDITOR_STATE)) +#define WEBKIT_EDITOR_STATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_EDITOR_STATE, WebKitEditorStateClass)) +#define WEBKIT_IS_EDITOR_STATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_EDITOR_STATE)) +#define WEBKIT_EDITOR_STATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_EDITOR_STATE, WebKitEditorStateClass)) + +typedef struct _WebKitEditorState WebKitEditorState; +typedef struct _WebKitEditorStateClass WebKitEditorStateClass; +typedef struct _WebKitEditorStatePrivate WebKitEditorStatePrivate; + +/** + * WebKitEditorTypingAttributes: + * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE: No typing attrubutes. + * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD: Bold typing attribute. + * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC: Italic typing attribute. + * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE: Underline typing attribute. + * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH: Strikethrough typing attribute. + * + * Enum values with flags representing typing attributes. + * + * Since: 2.10 + */ +typedef enum +{ + WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE = 1 << 1, + WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD = 1 << 2, + WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC = 1 << 3, + WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE = 1 << 4, + WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH = 1 << 5 +} WebKitEditorTypingAttributes; + +struct _WebKitEditorState { + GObject parent; + + WebKitEditorStatePrivate *priv; +}; + +struct _WebKitEditorStateClass { + GObjectClass parent_class; + + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); +}; + +WEBKIT_API GType +webkit_editor_state_get_type (void); + +WEBKIT_API guint +webkit_editor_state_get_typing_attributes (WebKitEditorState *editor_state); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCertificateInfoPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitEditorStatePrivate.h index ab3f1ef39..fdf9a35f5 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitCertificateInfoPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitEditorStatePrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Samsung Electronics Inc. All rights reserved. + * Copyright (C) 2015 Igalia S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,27 +17,13 @@ * Boston, MA 02110-1301, USA. */ -#ifndef WebKitCertificateInfoPrivate_h -#define WebKitCertificateInfoPrivate_h +#ifndef WebKitEditorStatePrivate_h +#define WebKitEditorStatePrivate_h -#include "WebKitCertificateInfo.h" +#include "WebKitEditorState.h" #include "WebKitPrivate.h" -#include <WebCore/CertificateInfo.h> -struct _WebKitCertificateInfo { - _WebKitCertificateInfo(GTlsCertificate* certificate, GTlsCertificateFlags tlsErrors) - : certificateInfo(certificate, tlsErrors) - { - } +WebKitEditorState* webkitEditorStateCreate(const WebKit::EditorState&); +void webkitEditorStateChanged(WebKitEditorState*, const WebKit::EditorState&); - _WebKitCertificateInfo(WebKitCertificateInfo* info) - : certificateInfo(info->certificateInfo) - { - } - - WebCore::CertificateInfo certificateInfo; -}; - -const WebCore::CertificateInfo& webkitCertificateInfoGetCertificateInfo(WebKitCertificateInfo*); - -#endif // WebKitCertificateInfoPrivate_h +#endif // WebKitEditorStatePrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp index c06dc61a5..7419ee721 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp @@ -40,53 +40,26 @@ GQuark webkit_network_error_quark() return g_quark_from_static_string(WebCore::errorDomainNetwork); } -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NETWORK_ERROR_FAILED, NetworkErrorFailed); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NETWORK_ERROR_TRANSPORT, NetworkErrorTransport); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL, NetworkErrorUnknownProtocol); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NETWORK_ERROR_CANCELLED, NetworkErrorCancelled); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST, NetworkErrorFileDoesNotExist); - GQuark webkit_policy_error_quark() { return g_quark_from_static_string(WebCore::errorDomainPolicy); } -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_POLICY_ERROR_FAILED, PolicyErrorFailed); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_POLICY_ERROR_CANNOT_SHOW_MIME_TYPE, PolicyErrorCannotShowMimeType); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_POLICY_ERROR_CANNOT_SHOW_URI, PolicyErrorCannotShowURL); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE, PolicyErrorFrameLoadInterruptedByPolicyChange); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT, PolicyErrorCannotUseRestrictedPort); - GQuark webkit_plugin_error_quark() { return g_quark_from_static_string(WebCore::errorDomainPlugin); } -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PLUGIN_ERROR_FAILED, PluginErrorFailed); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PLUGIN_ERROR_CANNOT_FIND_PLUGIN, PluginErrorCannotFindPlugin); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PLUGIN_ERROR_CANNOT_LOAD_PLUGIN, PluginErrorCannotLoadPlugin); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PLUGIN_ERROR_JAVA_UNAVAILABLE, PluginErrorJavaUnavailable); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PLUGIN_ERROR_CONNECTION_CANCELLED, PluginErrorConnectionCancelled); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PLUGIN_ERROR_WILL_HANDLE_LOAD, PluginErrorWillHandleLoad); - GQuark webkit_download_error_quark() { return g_quark_from_static_string(WebCore::errorDomainDownload); } -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_NETWORK, DownloadErrorNetwork); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER, DownloadErrorCancelledByUser); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_DESTINATION, DownloadErrorDestination); - GQuark webkit_print_error_quark() { return g_quark_from_static_string(WebCore::errorDomainPrint); } -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_GENERAL, PrintErrorGeneral); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND, PrintErrorPrinterNotFound); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE, PrintErrorInvalidPageRange); - GQuark webkit_javascript_error_quark() { return g_quark_from_static_string("WebKitJavascriptError"); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitError.h b/Source/WebKit2/UIProcess/API/gtk/WebKitError.h index e7de93bc2..9b6b75b38 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitError.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitError.h @@ -34,7 +34,7 @@ G_BEGIN_DECLS #define WEBKIT_PLUGIN_ERROR webkit_plugin_error_quark () #define WEBKIT_DOWNLOAD_ERROR webkit_download_error_quark () #define WEBKIT_PRINT_ERROR webkit_print_error_quark () -#define WEBKIT_JAVASCRIPT_ERROR webkit_print_error_quark () +#define WEBKIT_JAVASCRIPT_ERROR webkit_javascript_error_quark () #define WEBKIT_SNAPSHOT_ERROR webkit_snapshot_error_quark () /** diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFaviconDatabase.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFaviconDatabase.cpp index 0eda2729e..74654bb4f 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFaviconDatabase.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFaviconDatabase.cpp @@ -29,8 +29,8 @@ #include <WebCore/RefPtrCairo.h> #include <glib/gi18n-lib.h> #include <wtf/RunLoop.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -181,7 +181,7 @@ static void processPendingIconsForPageURL(WebKitFaviconDatabase* database, const deletePendingIconRequests(database, pendingIconRequests, pageURL); } -static void didChangeIconForPageURLCallback(WKIconDatabaseRef wkIconDatabase, WKURLRef wkPageURL, const void* clientInfo) +static void didChangeIconForPageURLCallback(WKIconDatabaseRef, WKURLRef wkPageURL, const void* clientInfo) { WebKitFaviconDatabase* database = WEBKIT_FAVICON_DATABASE(clientInfo); if (!database->priv->iconDatabase->isUrlImportCompleted()) @@ -203,7 +203,7 @@ static void didChangeIconForPageURLCallback(WKIconDatabaseRef wkIconDatabase, WK g_signal_emit(database, signals[FAVICON_CHANGED], 0, pageURL.utf8().data(), currentIconURL.utf8().data()); } -static void iconDataReadyForPageURLCallback(WKIconDatabaseRef wkIconDatabase, WKURLRef wkPageURL, const void* clientInfo) +static void iconDataReadyForPageURLCallback(WKIconDatabaseRef, WKURLRef wkPageURL, const void* clientInfo) { ASSERT(RunLoop::isMain()); processPendingIconsForPageURL(WEBKIT_FAVICON_DATABASE(clientInfo), toImpl(wkPageURL)->string()); @@ -259,6 +259,12 @@ GQuark webkit_favicon_database_error_quark(void) * This is an asynchronous method. When the operation is finished, callback will * be invoked. You can then call webkit_favicon_database_get_favicon_finish() * to get the result of the operation. + * + * You must call webkit_web_context_set_favicon_database_directory() for + * the #WebKitWebContext associated with this #WebKitFaviconDatabase + * before attempting to use this function; otherwise, + * webkit_favicon_database_get_favicon_finish() will return + * %WEBKIT_FAVICON_DATABASE_ERROR_NOT_INITIALIZED. */ void webkit_favicon_database_get_favicon(WebKitFaviconDatabase* database, const gchar* pageURI, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData) { diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp index 0855deea3..8b187a44e 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp @@ -21,14 +21,14 @@ #include "WebKitFileChooserRequest.h" #include "APIArray.h" +#include "APIOpenPanelParameters.h" #include "APIString.h" #include "WebKitFileChooserRequestPrivate.h" -#include "WebOpenPanelParameters.h" #include "WebOpenPanelResultListenerProxy.h" #include <WebCore/FileSystem.h> #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -59,7 +59,7 @@ using namespace WebCore; */ struct _WebKitFileChooserRequestPrivate { - RefPtr<WebOpenPanelParameters> parameters; + RefPtr<API::OpenPanelParameters> parameters; RefPtr<WebOpenPanelResultListenerProxy> listener; GRefPtr<GtkFileFilter> filter; GRefPtr<GPtrArray> mimeTypes; @@ -175,7 +175,7 @@ static void webkit_file_chooser_request_class_init(WebKitFileChooserRequestClass WEBKIT_PARAM_READABLE)); } -WebKitFileChooserRequest* webkitFileChooserRequestCreate(WebOpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener) +WebKitFileChooserRequest* webkitFileChooserRequestCreate(API::OpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener) { WebKitFileChooserRequest* request = WEBKIT_FILE_CHOOSER_REQUEST(g_object_new(WEBKIT_TYPE_FILE_CHOOSER_REQUEST, NULL)); request->priv->parameters = parameters; @@ -206,7 +206,7 @@ const gchar* const* webkit_file_chooser_request_get_mime_types(WebKitFileChooser if (request->priv->mimeTypes) return reinterpret_cast<gchar**>(request->priv->mimeTypes->pdata); - RefPtr<API::Array> mimeTypes = request->priv->parameters->acceptMIMETypes(); + Ref<API::Array> mimeTypes = request->priv->parameters->acceptMIMETypes(); size_t numOfMimeTypes = mimeTypes->size(); if (!numOfMimeTypes) return 0; @@ -247,7 +247,7 @@ GtkFileFilter* webkit_file_chooser_request_get_mime_types_filter(WebKitFileChoos if (request->priv->filter) return request->priv->filter.get(); - RefPtr<API::Array> mimeTypes = request->priv->parameters->acceptMIMETypes(); + Ref<API::Array> mimeTypes = request->priv->parameters->acceptMIMETypes(); size_t numOfMimeTypes = mimeTypes->size(); if (!numOfMimeTypes) return 0; @@ -299,23 +299,15 @@ void webkit_file_chooser_request_select_files(WebKitFileChooserRequest* request, g_return_if_fail(files); GRefPtr<GPtrArray> selectedFiles = adoptGRef(g_ptr_array_new_with_free_func(g_free)); - Vector<RefPtr<API::Object> > choosenFiles; + Vector<String> chosenFiles; for (int i = 0; files[i]; i++) { - GRefPtr<GFile> filename = adoptGRef(g_file_new_for_path(files[i])); - - // Make sure the file path is presented as an URI (escaped - // string, with the 'file://' prefix) to WebCore otherwise the - // FileChooser won't actually choose it. - GUniquePtr<char> uri(g_file_get_uri(filename.get())); - choosenFiles.append(API::URL::create(String::fromUTF8(uri.get()))); - - // Do not use the URI here because this won't reach WebCore. + chosenFiles.append(WebCore::decodeURLEscapeSequences(String::fromUTF8(files[i]))); g_ptr_array_add(selectedFiles.get(), g_strdup(files[i])); } - g_ptr_array_add(selectedFiles.get(), 0); + g_ptr_array_add(selectedFiles.get(), nullptr); // Select the files in WebCore and update local private attributes. - request->priv->listener->chooseFiles(API::Array::create(std::move(choosenFiles)).get()); + request->priv->listener->chooseFiles(chosenFiles); request->priv->selectedFiles = selectedFiles; request->priv->handledRequest = true; } @@ -354,7 +346,7 @@ const gchar* const* webkit_file_chooser_request_get_selected_files(WebKitFileCho request->priv->selectedFiles = adoptGRef(g_ptr_array_new_with_free_func(g_free)); for (size_t i = 0; i < numOfFiles; ++i) { API::String* webFileName = static_cast<API::String*>(selectedFileNames->at(i)); - if (webFileName->isEmpty()) + if (webFileName->stringView().isEmpty()) continue; CString filename = fileSystemRepresentation(webFileName->string()); g_ptr_array_add(request->priv->selectedFiles.get(), g_strdup(filename.data())); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h index 45d133e5b..8191ce748 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h @@ -23,6 +23,6 @@ #include "WebKitFileChooserRequest.h" #include "WebKitPrivate.h" -WebKitFileChooserRequest* webkitFileChooserRequestCreate(WebKit::WebOpenPanelParameters*, WebKit::WebOpenPanelResultListenerProxy*); +WebKitFileChooserRequest* webkitFileChooserRequestCreate(API::OpenPanelParameters*, WebKit::WebOpenPanelResultListenerProxy*); #endif // WebKitFileChooserRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.cpp index 8759306e2..0830bccaf 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.cpp @@ -25,7 +25,7 @@ #include "WebKitWebView.h" #include "WebKitWebViewBasePrivate.h" #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -73,6 +73,7 @@ typedef enum { struct _WebKitFindControllerPrivate { CString searchText; + // Interpreted as WebKit::FindOptions. uint32_t findOptions; unsigned maxMatchCount; WebKitWebView* webView; @@ -82,23 +83,35 @@ static guint signals[LAST_SIGNAL] = { 0, }; WEBKIT_DEFINE_TYPE(WebKitFindController, webkit_find_controller, G_TYPE_OBJECT) -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE, FindOptionsCaseInsensitive); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_AT_WORD_STARTS, FindOptionsAtWordStarts); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START, FindOptionsTreatMedialCapitalAsWordStart); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_BACKWARDS, FindOptionsBackwards); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_WRAP_AROUND, FindOptionsWrapAround); +static inline WebKit::FindOptions toWebFindOptions(uint32_t findOptions) +{ + return static_cast<WebKit::FindOptions>((findOptions & WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE ? FindOptionsCaseInsensitive : 0) + | (findOptions & WEBKIT_FIND_OPTIONS_AT_WORD_STARTS ? FindOptionsAtWordStarts : 0) + | (findOptions & WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START ? FindOptionsTreatMedialCapitalAsWordStart : 0) + | (findOptions & WEBKIT_FIND_OPTIONS_BACKWARDS ? FindOptionsBackwards : 0) + | (findOptions & WEBKIT_FIND_OPTIONS_WRAP_AROUND ? FindOptionsWrapAround : 0)); +} + +static inline WebKitFindOptions toWebKitFindOptions(uint32_t findOptions) +{ + return static_cast<WebKitFindOptions>((findOptions & FindOptionsCaseInsensitive ? WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE : 0) + | (findOptions & FindOptionsAtWordStarts ? WEBKIT_FIND_OPTIONS_AT_WORD_STARTS : 0) + | (findOptions & FindOptionsTreatMedialCapitalAsWordStart ? WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START : 0) + | (findOptions & FindOptionsBackwards ? WEBKIT_FIND_OPTIONS_BACKWARDS : 0) + | (findOptions & FindOptionsWrapAround ? WEBKIT_FIND_OPTIONS_WRAP_AROUND : 0)); +} -static void didFindString(WKPageRef page, WKStringRef string, unsigned matchCount, const void* clientInfo) +static void didFindString(WKPageRef, WKStringRef, unsigned matchCount, const void* clientInfo) { g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[FOUND_TEXT], 0, matchCount); } -static void didFailToFindString(WKPageRef page, WKStringRef string, const void* clientInfo) +static void didFailToFindString(WKPageRef, WKStringRef, const void* clientInfo) { g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[FAILED_TO_FIND_TEXT], 0); } -static void didCountStringMatches(WKPageRef page, WKStringRef string, unsigned matchCount, const void* clientInfo) +static void didCountStringMatches(WKPageRef, WKStringRef, unsigned matchCount, const void* clientInfo) { g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[COUNTED_MATCHES], 0, matchCount); } @@ -306,7 +319,7 @@ guint32 webkit_find_controller_get_options(WebKitFindController* findController) { g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), WEBKIT_FIND_OPTIONS_NONE); - return findController->priv->findOptions; + return toWebKitFindOptions(findController->priv->findOptions); } /** @@ -349,7 +362,7 @@ static void webKitFindControllerPerform(WebKitFindController* findController, We WebKitFindControllerPrivate* priv = findController->priv; if (operation == CountOperation) { getPage(findController)->countStringMatches(String::fromUTF8(priv->searchText.data()), - static_cast<WebKit::FindOptions>(priv->findOptions), priv->maxMatchCount); + static_cast<WebKit::FindOptions>(priv->findOptions), priv->maxMatchCount); return; } @@ -406,8 +419,7 @@ void webkit_find_controller_search(WebKitFindController* findController, const g { g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); g_return_if_fail(searchText); - - webKitFindControllerSetSearchData(findController, searchText, findOptions, maxMatchCount); + webKitFindControllerSetSearchData(findController, searchText, toWebFindOptions(findOptions), maxMatchCount); webKitFindControllerPerform(findController, FindOperation); } @@ -424,7 +436,7 @@ void webkit_find_controller_search_next(WebKitFindController* findController) { g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); - findController->priv->findOptions &= ~WEBKIT_FIND_OPTIONS_BACKWARDS; + findController->priv->findOptions &= ~FindOptionsBackwards; findController->priv->findOptions &= ~FindOptionsShowHighlight; webKitFindControllerPerform(findController, FindNextPrevOperation); } @@ -442,7 +454,7 @@ void webkit_find_controller_search_previous(WebKitFindController* findController { g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); - findController->priv->findOptions |= WEBKIT_FIND_OPTIONS_BACKWARDS; + findController->priv->findOptions |= FindOptionsBackwards; findController->priv->findOptions &= ~FindOptionsShowHighlight; webKitFindControllerPerform(findController, FindNextPrevOperation); } @@ -464,7 +476,7 @@ void webkit_find_controller_count_matches(WebKitFindController* findController, g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); g_return_if_fail(searchText); - webKitFindControllerSetSearchData(findController, searchText, findOptions, maxMatchCount); + webKitFindControllerSetSearchData(findController, searchText, toWebFindOptions(findOptions), maxMatchCount); webKitFindControllerPerform(findController, CountOperation); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h index 7bad1d051..8f3e438ff 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h @@ -62,7 +62,7 @@ typedef enum { WEBKIT_FIND_OPTIONS_AT_WORD_STARTS = 1 << 1, WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START = 1 << 2, WEBKIT_FIND_OPTIONS_BACKWARDS = 1 << 3, - WEBKIT_FIND_OPTIONS_WRAP_AROUND = 1 << 4, + WEBKIT_FIND_OPTIONS_WRAP_AROUND = 1 << 4 } WebKitFindOptions; struct _WebKitFindController { diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFormClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFormClient.cpp index a07f04948..12ec927a8 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFormClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFormClient.cpp @@ -20,15 +20,17 @@ #include "config.h" #include "WebKitFormClient.h" +#include "APIDictionary.h" +#include "WebFormSubmissionListenerProxy.h" #include "WebKitFormSubmissionRequestPrivate.h" #include "WebKitPrivate.h" #include "WebKitWebViewBasePrivate.h" #include "WebKitWebViewPrivate.h" -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> using namespace WebKit; -static void willSubmitForm(WKPageRef page, WKFrameRef frame, WKFrameRef sourceFrame, WKDictionaryRef values, WKTypeRef userData, WKFormSubmissionListenerRef listener, const void* clientInfo) +static void willSubmitForm(WKPageRef, WKFrameRef, WKFrameRef, WKDictionaryRef values, WKTypeRef /* userData */, WKFormSubmissionListenerRef listener, const void* clientInfo) { GRefPtr<WebKitFormSubmissionRequest> request = adoptGRef(webkitFormSubmissionRequestCreate(toImpl(values), toImpl(listener))); webkitWebViewSubmitFormRequest(WEBKIT_WEB_VIEW(clientInfo), request.get()); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequest.cpp index 8519a2cb6..7af2aee10 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequest.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequest.cpp @@ -20,11 +20,11 @@ #include "config.h" #include "WebKitFormSubmissionRequest.h" +#include "APIDictionary.h" #include "APIString.h" -#include "ImmutableDictionary.h" #include "WebFormSubmissionListenerProxy.h" #include "WebKitFormSubmissionRequestPrivate.h" -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -45,7 +45,7 @@ using namespace WebKit; */ struct _WebKitFormSubmissionRequestPrivate { - RefPtr<ImmutableDictionary> webValues; + RefPtr<API::Dictionary> webValues; RefPtr<WebFormSubmissionListenerProxy> listener; GRefPtr<GHashTable> values; bool handledRequest; @@ -70,7 +70,7 @@ static void webkit_form_submission_request_class_init(WebKitFormSubmissionReques objectClass->dispose = webkitFormSubmissionRequestDispose; } -WebKitFormSubmissionRequest* webkitFormSubmissionRequestCreate(ImmutableDictionary* values, WebFormSubmissionListenerProxy* listener) +WebKitFormSubmissionRequest* webkitFormSubmissionRequestCreate(API::Dictionary* values, WebFormSubmissionListenerProxy* listener) { WebKitFormSubmissionRequest* request = WEBKIT_FORM_SUBMISSION_REQUEST(g_object_new(WEBKIT_TYPE_FORM_SUBMISSION_REQUEST, NULL)); request->priv->webValues = values; @@ -96,18 +96,18 @@ GHashTable* webkit_form_submission_request_get_text_fields(WebKitFormSubmissionR return request->priv->values.get(); if (!request->priv->webValues->size()) - return 0; + return nullptr; request->priv->values = adoptGRef(g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free)); - const ImmutableDictionary::MapType& map = request->priv->webValues->map(); - ImmutableDictionary::MapType::const_iterator end = map.end(); - for (ImmutableDictionary::MapType::const_iterator it = map.begin(); it != end; ++it) { + const API::Dictionary::MapType& map = request->priv->webValues->map(); + API::Dictionary::MapType::const_iterator end = map.end(); + for (API::Dictionary::MapType::const_iterator it = map.begin(); it != end; ++it) { API::String* value = static_cast<API::String*>(it->value.get()); g_hash_table_insert(request->priv->values.get(), g_strdup(it->key.utf8().data()), g_strdup(value->string().utf8().data())); } - request->priv->webValues = 0; + request->priv->webValues = nullptr; return request->priv->values.get(); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequestPrivate.h index 9fe4751d2..1d2b499f6 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequestPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequestPrivate.h @@ -23,6 +23,6 @@ #include "WebKitFormSubmissionRequest.h" #include "WebKitPrivate.h" -WebKitFormSubmissionRequest* webkitFormSubmissionRequestCreate(WebKit::ImmutableDictionary* values, WebKit::WebFormSubmissionListenerProxy*); +WebKitFormSubmissionRequest* webkitFormSubmissionRequestCreate(API::Dictionary* values, WebKit::WebFormSubmissionListenerProxy*); #endif // WebKitFormSubmissionRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitForwardDeclarations.h b/Source/WebKit2/UIProcess/API/gtk/WebKitForwardDeclarations.h index a9898de48..543f4b136 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitForwardDeclarations.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitForwardDeclarations.h @@ -23,7 +23,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__) #error "Only <webkit2/webkit2.h> can be included directly." #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequest.cpp index f780dafb2..871c3cf3e 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequest.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequest.cpp @@ -35,6 +35,9 @@ using namespace WebKit; * WebKitGeolocationPermissionRequest represents a request for * permission to decide whether WebKit should provide the user's * location to a website when requested throught the Geolocation API. + * + * When a WebKitGeolocationPermissionRequest is not handled by the user, + * it is denied by default. */ static void webkit_permission_request_interface_init(WebKitPermissionRequestIface*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.cpp index 261abf81a..6ac0fbc98 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.cpp @@ -38,12 +38,12 @@ static inline WebKitGeolocationProvider* toGeolocationProvider(const void* clien return static_cast<WebKitGeolocationProvider*>(const_cast<void*>(clientInfo)); } -static void startUpdatingCallback(WKGeolocationManagerRef geolocationManager, const void* clientInfo) +static void startUpdatingCallback(WKGeolocationManagerRef, const void* clientInfo) { toGeolocationProvider(clientInfo)->startUpdating(); } -static void stopUpdatingCallback(WKGeolocationManagerRef geolocationManager, const void* clientInfo) +static void stopUpdatingCallback(WKGeolocationManagerRef, const void* clientInfo) { toGeolocationProvider(clientInfo)->stopUpdating(); } @@ -51,11 +51,12 @@ static void stopUpdatingCallback(WKGeolocationManagerRef geolocationManager, con WebKitGeolocationProvider::~WebKitGeolocationProvider() { m_provider.stopUpdating(); + WKGeolocationManagerSetProvider(toAPI(m_geolocationManager.get()), nullptr); } -PassRefPtr<WebKitGeolocationProvider> WebKitGeolocationProvider::create(WebGeolocationManagerProxy* geolocationManager) +Ref<WebKitGeolocationProvider> WebKitGeolocationProvider::create(WebGeolocationManagerProxy* geolocationManager) { - return adoptRef(new WebKitGeolocationProvider(geolocationManager)); + return adoptRef(*new WebKitGeolocationProvider(geolocationManager)); } WebKitGeolocationProvider::WebKitGeolocationProvider(WebGeolocationManagerProxy* geolocationManager) @@ -92,7 +93,7 @@ void WebKitGeolocationProvider::notifyPositionChanged(int timestamp, double lati m_geolocationManager->providerDidChangePosition(position.get()); } -void WebKitGeolocationProvider::notifyErrorOccurred(const char* message) +void WebKitGeolocationProvider::notifyErrorOccurred(const char* /* message */) { m_geolocationManager->providerDidFailToDeterminePosition(); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.h b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.h index e6be3eac2..e18dc56ac 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.h @@ -25,7 +25,7 @@ #include "WebKitPrivate.h" #include <WebCore/GeolocationProviderGeoclue.h> #include <WebCore/GeolocationProviderGeoclueClient.h> -#include <wtf/PassRefPtr.h> +#include <wtf/Ref.h> #include <wtf/RefCounted.h> namespace WebKit { @@ -33,7 +33,7 @@ namespace WebKit { class WebKitGeolocationProvider : public RefCounted<WebKitGeolocationProvider>, public WebCore::GeolocationProviderGeoclueClient { public: virtual ~WebKitGeolocationProvider(); - static PassRefPtr<WebKitGeolocationProvider> create(WebGeolocationManagerProxy*); + static Ref<WebKitGeolocationProvider> create(WebGeolocationManagerProxy*); void startUpdating(); void stopUpdating(); @@ -42,8 +42,8 @@ private: WebKitGeolocationProvider(WebGeolocationManagerProxy*); // GeolocationProviderGeoclueClient interface. - virtual void notifyPositionChanged(int, double, double, double, double, double); - virtual void notifyErrorOccurred(const char*); + void notifyPositionChanged(int, double, double, double, double, double) override; + void notifyErrorOccurred(const char*) override; RefPtr<WebGeolocationManagerProxy> m_geolocationManager; WebCore::GeolocationProviderGeoclue m_provider; diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.cpp index 918d316c0..60b5fb853 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.cpp @@ -20,7 +20,7 @@ #include "config.h" #include "WebKitHitTestResult.h" -#include "WebHitTestResult.h" +#include "WebHitTestResultData.h" #include "WebKitHitTestResultPrivate.h" #include <glib/gi18n-lib.h> #include <wtf/text/CString.h> @@ -221,39 +221,36 @@ static void webkit_hit_test_result_class_init(WebKitHitTestResultClass* hitTestR paramFlags)); } -WebKitHitTestResult* webkitHitTestResultCreate(WebHitTestResult* hitTestResult) +WebKitHitTestResult* webkitHitTestResultCreate(const WebHitTestResultData& hitTestResult) { unsigned context = WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT; - const String& linkURL = hitTestResult->absoluteLinkURL(); - if (!linkURL.isEmpty()) + if (!hitTestResult.absoluteLinkURL.isEmpty()) context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK; - const String& imageURL = hitTestResult->absoluteImageURL(); - if (!imageURL.isEmpty()) + if (!hitTestResult.absoluteImageURL.isEmpty()) context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE; - const String& mediaURL = hitTestResult->absoluteMediaURL(); - if (!mediaURL.isEmpty()) + if (!hitTestResult.absoluteMediaURL.isEmpty()) context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA; - if (hitTestResult->isContentEditable()) + if (hitTestResult.isContentEditable) context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE; - if (hitTestResult->isScrollbar()) + if (hitTestResult.isScrollbar) context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR; - const String& linkTitle = hitTestResult->linkTitle(); - const String& linkLabel = hitTestResult->linkLabel(); + if (hitTestResult.isSelected) + context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION; return WEBKIT_HIT_TEST_RESULT(g_object_new(WEBKIT_TYPE_HIT_TEST_RESULT, - "context", context, - "link-uri", !linkURL.isEmpty() ? linkURL.utf8().data() : 0, - "image-uri", !imageURL.isEmpty() ? imageURL.utf8().data() : 0, - "media-uri", !mediaURL.isEmpty() ? mediaURL.utf8().data() : 0, - "link-title", !linkTitle.isEmpty() ? linkTitle.utf8().data() : 0, - "link-label", !linkLabel.isEmpty() ? linkLabel.utf8().data() : 0, - NULL)); + "context", context, + "link-uri", context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK ? hitTestResult.absoluteLinkURL.utf8().data() : nullptr, + "image-uri", context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE ? hitTestResult.absoluteImageURL.utf8().data() : nullptr, + "media-uri", context & WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA ? hitTestResult.absoluteMediaURL.utf8().data() : nullptr, + "link-title", !hitTestResult.linkTitle.isEmpty() ? hitTestResult.linkTitle.utf8().data() : nullptr, + "link-label", !hitTestResult.linkLabel.isEmpty() ? hitTestResult.linkLabel.utf8().data() : nullptr, + nullptr)); } static bool stringIsEqualToCString(const String& string, const CString& cString) @@ -261,16 +258,17 @@ static bool stringIsEqualToCString(const String& string, const CString& cString) return ((string.isEmpty() && cString.isNull()) || (string.utf8() == cString)); } -bool webkitHitTestResultCompare(WebKitHitTestResult* hitTestResult, WebHitTestResult* webHitTestResult) +bool webkitHitTestResultCompare(WebKitHitTestResult* hitTestResult, const WebHitTestResultData& webHitTestResult) { WebKitHitTestResultPrivate* priv = hitTestResult->priv; - return webHitTestResult->isContentEditable() == webkit_hit_test_result_context_is_editable(hitTestResult) - && webHitTestResult->isScrollbar() == webkit_hit_test_result_context_is_scrollbar(hitTestResult) - && stringIsEqualToCString(webHitTestResult->absoluteLinkURL(), priv->linkURI) - && stringIsEqualToCString(webHitTestResult->linkTitle(), priv->linkTitle) - && stringIsEqualToCString(webHitTestResult->linkLabel(), priv->linkLabel) - && stringIsEqualToCString(webHitTestResult->absoluteImageURL(), priv->imageURI) - && stringIsEqualToCString(webHitTestResult->absoluteMediaURL(), priv->mediaURI); + return webHitTestResult.isContentEditable == webkit_hit_test_result_context_is_editable(hitTestResult) + && webHitTestResult.isScrollbar == webkit_hit_test_result_context_is_scrollbar(hitTestResult) + && webHitTestResult.isSelected == webkit_hit_test_result_context_is_selection(hitTestResult) + && stringIsEqualToCString(webHitTestResult.absoluteLinkURL, priv->linkURI) + && stringIsEqualToCString(webHitTestResult.linkTitle, priv->linkTitle) + && stringIsEqualToCString(webHitTestResult.linkLabel, priv->linkLabel) + && stringIsEqualToCString(webHitTestResult.absoluteImageURL, priv->imageURI) + && stringIsEqualToCString(webHitTestResult.absoluteMediaURL, priv->mediaURI); } /** @@ -357,6 +355,25 @@ gboolean webkit_hit_test_result_context_is_editable(WebKitHitTestResult* hitTest } /** + * webkit_hit_test_result_context_is_selection: + * @hit_test_result: a #WebKitHitTestResult + * + * Gets whether %WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION flag is present in + * #WebKitHitTestResult:context. + * + * Returns: %TRUE if there's a selected element at the coordinates of the @hit_test_result, + * or %FALSE otherwise + * + * Since: 2.8 + */ +gboolean webkit_hit_test_result_context_is_selection(WebKitHitTestResult* hitTestResult) +{ + g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), FALSE); + + return hitTestResult->priv->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION; +} + +/** * webkit_hit_test_result_get_link_uri: * @hit_test_result: a #WebKitHitTestResult * diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h index 54611ba92..718573b90 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h @@ -17,7 +17,7 @@ * Boston, MA 02110-1301, USA. */ -#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__) #error "Only <webkit2/webkit2.h> can be included directly." #endif @@ -48,6 +48,7 @@ typedef struct _WebKitHitTestResultPrivate WebKitHitTestResultPrivate; * @WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA: a video or audio element. * @WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE: an editable element * @WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR: a scrollbar element. + * @WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION: a selected element. Since 2.8 * * Enum values with flags representing the context of a #WebKitHitTestResult. */ @@ -58,7 +59,8 @@ typedef enum WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE = 1 << 3, WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA = 1 << 4, WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE = 1 << 5, - WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR = 1 << 6 + WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR = 1 << 6, + WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION = 1 << 7 } WebKitHitTestResultContext; struct _WebKitHitTestResult { @@ -94,6 +96,9 @@ webkit_hit_test_result_context_is_media (WebKitHitTestResult *hit_test_resul WEBKIT_API gboolean webkit_hit_test_result_context_is_editable (WebKitHitTestResult *hit_test_result); +WEBKIT_API gboolean +webkit_hit_test_result_context_is_selection (WebKitHitTestResult *hit_test_result); + WEBKIT_API const gchar * webkit_hit_test_result_get_link_uri (WebKitHitTestResult *hit_test_result); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResultPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResultPrivate.h index 7ba2c3871..4fdb46deb 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResultPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResultPrivate.h @@ -23,7 +23,7 @@ #include "WebKitHitTestResult.h" #include "WebKitPrivate.h" -WebKitHitTestResult* webkitHitTestResultCreate(WebKit::WebHitTestResult*); -bool webkitHitTestResultCompare(WebKitHitTestResult*, WebKit::WebHitTestResult*); +WebKitHitTestResult* webkitHitTestResultCreate(const WebKit::WebHitTestResultData&); +bool webkitHitTestResultCompare(WebKitHitTestResult*, const WebKit::WebHitTestResultData&); #endif // WebKitHitTestResultPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitInjectedBundleClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitInjectedBundleClient.cpp index 1b77b6ea7..0ec44d463 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitInjectedBundleClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitInjectedBundleClient.cpp @@ -21,17 +21,18 @@ #include "WebKitInjectedBundleClient.h" #include "WebImage.h" +#include "WebKitPrivate.h" #include "WebKitURIRequestPrivate.h" #include "WebKitURIResponsePrivate.h" #include "WebKitWebContextPrivate.h" #include "WebKitWebResourcePrivate.h" #include "WebKitWebViewPrivate.h" -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GUniquePtr.h> using namespace WebKit; using namespace WebCore; -static void didReceiveWebViewMessageFromInjectedBundle(WebKitWebView* webView, const char* messageName, ImmutableDictionary& message) +static void didReceiveWebViewMessageFromInjectedBundle(WebKitWebView* webView, const char* messageName, API::Dictionary& message) { if (g_str_equal(messageName, "DidInitiateLoadForResource")) { WebFrameProxy* frame = static_cast<WebFrameProxy*>(message.get(String::fromUTF8("Frame"))); @@ -87,9 +88,12 @@ static void didReceiveWebViewMessageFromInjectedBundle(WebKitWebView* webView, c API::Error* webError = static_cast<API::Error*>(message.get(String::fromUTF8("Error"))); const ResourceError& platformError = webError->platformError(); GUniquePtr<GError> resourceError(g_error_new_literal(g_quark_from_string(platformError.domain().utf8().data()), - platformError.errorCode(), platformError.localizedDescription().utf8().data())); + toWebKitError(platformError.errorCode()), platformError.localizedDescription().utf8().data())); + if (platformError.tlsErrors()) + webkitWebResourceFailedWithTLSErrors(resource.get(), static_cast<GTlsCertificateFlags>(platformError.tlsErrors()), platformError.certificate()); + else + webkitWebResourceFailed(resource.get(), resourceError.get()); - webkitWebResourceFailed(resource.get(), resourceError.get()); webkitWebViewRemoveLoadingWebResource(webView, resourceIdentifier->value()); } else if (g_str_equal(messageName, "DidGetSnapshot")) { API::UInt64* callbackID = static_cast<API::UInt64*>(message.get("CallbackID")); @@ -102,7 +106,7 @@ static void didReceiveWebViewMessageFromInjectedBundle(WebKitWebView* webView, c static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); - ImmutableDictionary& message = *toImpl(static_cast<WKDictionaryRef>(messageBody)); + API::Dictionary& message = *toImpl(static_cast<WKDictionaryRef>(messageBody)); CString messageNameCString = toImpl(messageName)->string().utf8(); const char* messageNameUTF8 = messageNameCString.data(); @@ -136,5 +140,5 @@ void attachInjectedBundleClientToContext(WebKitWebContext* webContext) 0, // didReceiveSynchronousMessageFromInjectedBundle getInjectedBundleInitializationUserData }; - WKContextSetInjectedBundleClient(toAPI(webkitWebContextGetContext(webContext)), &wkInjectedBundleClient.base); + WKContextSetInjectedBundleClient(toAPI(&webkitWebContextGetProcessPool(webContext)), &wkInjectedBundleClient.base); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequest.cpp new file mode 100644 index 000000000..d516b61ad --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequest.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitInstallMissingMediaPluginsPermissionRequest.h" + +#include "WebKitInstallMissingMediaPluginsPermissionRequestPrivate.h" +#include "WebKitPermissionRequest.h" +#include "WebPageProxy.h" + +#if ENABLE(VIDEO) +#include <WebCore/PlatformDisplay.h> +#include <gtk/gtk.h> +#if PLATFORM(X11) +#include <gdk/gdkx.h> +#endif +#endif + +using namespace WebKit; +using namespace WebCore; + +/** + * SECTION: WebKitInstallMissingMediaPluginsPermissionRequest + * @Short_description: A permission request for installing missing media plugins + * @Title: WebKitInstallMissingMediaPluginsPermissionRequest + * @See_also: #WebKitPermissionRequest, #WebKitWebView + * + * WebKitInstallMissingMediaPluginsPermissionRequest represents a request for + * permission to decide whether WebKit should try to start a helper application to + * install missing media plugins when the media backend couldn't play a media because + * the required plugins were not available. + * + * When a WebKitInstallMissingMediaPluginsPermissionRequest is not handled by the user, + * it is allowed by default. + * + * Since: 2.10 + */ + +static void webkit_permission_request_interface_init(WebKitPermissionRequestIface*); + +struct _WebKitInstallMissingMediaPluginsPermissionRequestPrivate { +#if ENABLE(VIDEO) + RefPtr<InstallMissingMediaPluginsPermissionRequest> request; +#endif + CString description; + bool madeDecision; +}; + +WEBKIT_DEFINE_TYPE_WITH_CODE( + WebKitInstallMissingMediaPluginsPermissionRequest, webkit_install_missing_media_plugins_permission_request, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(WEBKIT_TYPE_PERMISSION_REQUEST, webkit_permission_request_interface_init)) + +#if ENABLE(VIDEO) +static GUniquePtr<GstInstallPluginsContext> createGstInstallPluginsContext(GtkWidget* widget) +{ +#if PLATFORM(X11) + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11) { + GUniquePtr<GstInstallPluginsContext> context(gst_install_plugins_context_new()); + gst_install_plugins_context_set_xid(context.get(), GDK_WINDOW_XID(gtk_widget_get_window(widget))); + return context; + } +#endif + + return nullptr; +} +#endif + +static void webkitInstallMissingMediaPluginsPermissionRequestAllow(WebKitPermissionRequest* request) +{ + ASSERT(WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request)); + + WebKitInstallMissingMediaPluginsPermissionRequestPrivate* priv = WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request)->priv; + + // Only one decision at a time. + if (priv->madeDecision) + return; +#if ENABLE(VIDEO) + priv->request->allow(createGstInstallPluginsContext(priv->request->page().viewWidget())); +#endif + priv->madeDecision = true; +} + +static void webkitInstallMissingMediaPluginsPermissionRequestDeny(WebKitPermissionRequest* request) +{ + ASSERT(WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request)); + + WebKitInstallMissingMediaPluginsPermissionRequestPrivate* priv = WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request)->priv; + + // Only one decision at a time. + if (priv->madeDecision) + return; + +#if ENABLE(VIDEO) + priv->request->deny(); +#endif + priv->madeDecision = true; +} + +static void webkit_permission_request_interface_init(WebKitPermissionRequestIface* iface) +{ + iface->allow = webkitInstallMissingMediaPluginsPermissionRequestAllow; + iface->deny = webkitInstallMissingMediaPluginsPermissionRequestDeny; +} + +static void webkitInstallMissingMediaPluginsPermissionRequestDispose(GObject* object) +{ + // Default behaviour when no decision has been made is allowing the request for backwards compatibility. + webkitInstallMissingMediaPluginsPermissionRequestDeny(WEBKIT_PERMISSION_REQUEST(object)); + G_OBJECT_CLASS(webkit_install_missing_media_plugins_permission_request_parent_class)->dispose(object); +} + +static void webkit_install_missing_media_plugins_permission_request_class_init(WebKitInstallMissingMediaPluginsPermissionRequestClass* klass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(klass); + objectClass->dispose = webkitInstallMissingMediaPluginsPermissionRequestDispose; +} + +#if ENABLE(VIDEO) +WebKitInstallMissingMediaPluginsPermissionRequest* webkitInstallMissingMediaPluginsPermissionRequestCreate(InstallMissingMediaPluginsPermissionRequest& request) +{ + WebKitInstallMissingMediaPluginsPermissionRequest* permissionRequest = WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(g_object_new(WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST, nullptr)); + permissionRequest->priv->request = &request; + return permissionRequest; +} +#endif + +/** + * webkit_install_missing_media_plugins_permission_request_get_description: + * @request: a #WebKitInstallMissingMediaPluginsPermissionRequest + * + * Gets the description about the missing plugins provided by the media backend when a media couldn't be played. + * + * Returns: a string with the description provided by the media backend. + * + * Since: 2.10 + */ +const char* webkit_install_missing_media_plugins_permission_request_get_description(WebKitInstallMissingMediaPluginsPermissionRequest* request) +{ + g_return_val_if_fail(WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request), nullptr); + +#if ENABLE(VIDEO) + if (!request->priv->description.isNull()) + return request->priv->description.data(); + + const auto& description = request->priv->request->description(); + ASSERT(!description.isEmpty()); + request->priv->description = description.utf8(); +#endif + return request->priv->description.data(); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequest.h b/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequest.h new file mode 100644 index 000000000..e0632afa5 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequest.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitInstallMissingMediaPluginsPermissionRequest_h +#define WebKitInstallMissingMediaPluginsPermissionRequest_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST (webkit_install_missing_media_plugins_permission_request_get_type()) +#define WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST, WebKitInstallMissingMediaPluginsPermissionRequest)) +#define WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST)) +#define WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST, WebKitInstallMissingMediaPluginsPermissionRequestClass)) +#define WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST)) +#define WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST, WebKitInstallMissingMediaPluginsPermissionRequestClass)) + +typedef struct _WebKitInstallMissingMediaPluginsPermissionRequest WebKitInstallMissingMediaPluginsPermissionRequest; +typedef struct _WebKitInstallMissingMediaPluginsPermissionRequestClass WebKitInstallMissingMediaPluginsPermissionRequestClass; +typedef struct _WebKitInstallMissingMediaPluginsPermissionRequestPrivate WebKitInstallMissingMediaPluginsPermissionRequestPrivate; + +struct _WebKitInstallMissingMediaPluginsPermissionRequest { + GObject parent; + + WebKitInstallMissingMediaPluginsPermissionRequestPrivate *priv; +}; + +struct _WebKitInstallMissingMediaPluginsPermissionRequestClass { + GObjectClass parent_class; + + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); +}; + +WEBKIT_API GType +webkit_install_missing_media_plugins_permission_request_get_type (void); + +WEBKIT_API const gchar * +webkit_install_missing_media_plugins_permission_request_get_description (WebKitInstallMissingMediaPluginsPermissionRequest *request); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequestPrivate.h new file mode 100644 index 000000000..2c7e3bc0d --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequestPrivate.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitInstallMissingMediaPluginsPermissionRequestPrivate_h +#define WebKitInstallMissingMediaPluginsPermissionRequestPrivate_h + +#include "InstallMissingMediaPluginsPermissionRequest.h" +#include "WebKitInstallMissingMediaPluginsPermissionRequest.h" +#include "WebKitPrivate.h" + +#if ENABLE(VIDEO) +WebKitInstallMissingMediaPluginsPermissionRequest* webkitInstallMissingMediaPluginsPermissionRequestCreate(WebKit::InstallMissingMediaPluginsPermissionRequest&); +#endif + +#endif // WebKitInstallMissingMediaPluginsPermissionRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp index 9bbd3f4ed..79ec69b70 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp @@ -20,18 +20,18 @@ #include "config.h" #include "WebKitJavascriptResult.h" +#include "APISerializedScriptValue.h" #include "WebKitJavascriptResultPrivate.h" -#include "WebSerializedScriptValue.h" -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> using namespace WebKit; struct _WebKitJavascriptResult { - _WebKitJavascriptResult(WebKitWebView* view, WebSerializedScriptValue* serializedScriptValue) + _WebKitJavascriptResult(WebKitWebView* view, WebCore::SerializedScriptValue& serializedScriptValue) : webView(view) , referenceCount(1) { - value = serializedScriptValue->deserialize(webkit_web_view_get_javascript_global_context(view), 0); + value = serializedScriptValue.deserialize(webkit_web_view_get_javascript_global_context(view), nullptr); } GRefPtr<WebKitWebView> webView; @@ -42,9 +42,9 @@ struct _WebKitJavascriptResult { G_DEFINE_BOXED_TYPE(WebKitJavascriptResult, webkit_javascript_result, webkit_javascript_result_ref, webkit_javascript_result_unref) -WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView* webView, WebSerializedScriptValue* serializedScriptValue) +WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView* webView, WebCore::SerializedScriptValue& serializedScriptValue) { - WebKitJavascriptResult* result = g_slice_new(WebKitJavascriptResult); + WebKitJavascriptResult* result = static_cast<WebKitJavascriptResult*>(fastMalloc(sizeof(WebKitJavascriptResult))); new (result) WebKitJavascriptResult(webView, serializedScriptValue); return result; } @@ -77,7 +77,7 @@ void webkit_javascript_result_unref(WebKitJavascriptResult* javascriptResult) { if (g_atomic_int_dec_and_test(&javascriptResult->referenceCount)) { javascriptResult->~WebKitJavascriptResult(); - g_slice_free(WebKitJavascriptResult, javascriptResult); + fastFree(javascriptResult); } } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h index e47e94c1b..23e2e7926 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h @@ -20,10 +20,11 @@ #ifndef WebKitJavascriptResultPrivate_h #define WebKitJavascriptResultPrivate_h +#include <WebCore/SerializedScriptValue.h> #include "WebKitJavascriptResult.h" #include "WebKitPrivate.h" #include "WebKitWebView.h" -WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView*, WebKit::WebSerializedScriptValue*); +WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView*, WebCore::SerializedScriptValue&); #endif // WebKitJavascriptResultPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp index 4b2e59c25..f52c8c78e 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp @@ -21,166 +21,107 @@ #include "config.h" #include "WebKitLoaderClient.h" +#include "APILoaderClient.h" #include "WebKitBackForwardListPrivate.h" +#include "WebKitPrivate.h" #include "WebKitURIResponsePrivate.h" #include "WebKitWebViewBasePrivate.h" #include "WebKitWebViewPrivate.h" -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> using namespace WebKit; using namespace WebCore; -static void didStartProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frame)) - return; - - webkitWebViewLoadChanged(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_STARTED); -} - -static void didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frame)) - return; - - webkitWebViewLoadChanged(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_REDIRECTED); -} - -static void didFailProvisionalLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, WKErrorRef error, WKTypeRef userData, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frame)) - return; - - const ResourceError& resourceError = toImpl(error)->platformError(); - GUniquePtr<GError> webError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()), - resourceError.errorCode(), resourceError.localizedDescription().utf8().data())); - if (resourceError.tlsErrors()) { - webkitWebViewLoadFailedWithTLSErrors(WEBKIT_WEB_VIEW(clientInfo), resourceError.failingURL().utf8().data(), webError.get(), - static_cast<GTlsCertificateFlags>(resourceError.tlsErrors()), resourceError.certificate()); - } else - webkitWebViewLoadFailed(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_STARTED, resourceError.failingURL().utf8().data(), webError.get()); -} - -static void didCommitLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frame)) - return; - - webkitWebViewLoadChanged(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_COMMITTED); -} - -static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frame)) - return; - - webkitWebViewLoadChanged(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_FINISHED); -} - -static void didFailLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, WKErrorRef error, WKTypeRef, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frame)) - return; - - const ResourceError& resourceError = toImpl(error)->platformError(); - GUniquePtr<GError> webError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()), - resourceError.errorCode(), resourceError.localizedDescription().utf8().data())); - webkitWebViewLoadFailed(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_COMMITTED, - resourceError.failingURL().utf8().data(), webError.get()); -} - -static void didSameDocumentNavigationForFrame(WKPageRef page, WKFrameRef frame, WKSameDocumentNavigationType, WKTypeRef, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frame)) - return; - - webkitWebViewUpdateURI(WEBKIT_WEB_VIEW(clientInfo)); -} - -static void didReceiveTitleForFrame(WKPageRef page, WKStringRef titleRef, WKFrameRef frameRef, WKTypeRef, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frameRef)) - return; - - webkitWebViewSetTitle(WEBKIT_WEB_VIEW(clientInfo), toImpl(titleRef)->string().utf8()); -} - -static void didDisplayInsecureContentForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) -{ - webkitWebViewInsecureContentDetected(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_INSECURE_CONTENT_DISPLAYED); -} - -static void didRunInsecureContentForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) -{ - webkitWebViewInsecureContentDetected(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_INSECURE_CONTENT_RUN); -} - -static void didChangeProgress(WKPageRef page, const void* clientInfo) -{ - webkitWebViewSetEstimatedLoadProgress(WEBKIT_WEB_VIEW(clientInfo), WKPageGetEstimatedProgress(page)); -} - -static void didChangeBackForwardList(WKPageRef page, WKBackForwardListItemRef addedItem, WKArrayRef removedItems, const void* clientInfo) -{ - webkitBackForwardListChanged(webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(clientInfo)), toImpl(addedItem), toImpl(removedItems)); -} - -static void didReceiveAuthenticationChallengeInFrame(WKPageRef page, WKFrameRef frame, WKAuthenticationChallengeRef authenticationChallenge, const void *clientInfo) -{ - webkitWebViewHandleAuthenticationChallenge(WEBKIT_WEB_VIEW(clientInfo), toImpl(authenticationChallenge)); -} - -static void processDidCrash(WKPageRef page, const void* clientInfo) -{ - webkitWebViewWebProcessCrashed(WEBKIT_WEB_VIEW(clientInfo)); -} +class LoaderClient : public API::LoaderClient { +public: + explicit LoaderClient(WebKitWebView* webView) + : m_webView(webView) + { + } + +private: + void didStartProvisionalLoadForFrame(WebPageProxy&, WebFrameProxy& frame, API::Navigation*, API::Object* /* userData */) override + { + if (!frame.isMainFrame()) + return; + webkitWebViewLoadChanged(m_webView, WEBKIT_LOAD_STARTED); + } + + void didReceiveServerRedirectForProvisionalLoadForFrame(WebPageProxy&, WebFrameProxy& frame, API::Navigation*, API::Object* /* userData */) override + { + if (!frame.isMainFrame()) + return; + webkitWebViewLoadChanged(m_webView, WEBKIT_LOAD_REDIRECTED); + } + + void didFailProvisionalLoadWithErrorForFrame(WebPageProxy&, WebFrameProxy& frame, API::Navigation*, const ResourceError& resourceError, API::Object* /* userData */) override + { + if (!frame.isMainFrame()) + return; + GUniquePtr<GError> error(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()), + toWebKitError(resourceError.errorCode()), resourceError.localizedDescription().utf8().data())); + if (resourceError.tlsErrors()) { + webkitWebViewLoadFailedWithTLSErrors(m_webView, resourceError.failingURL().string().utf8().data(), error.get(), + static_cast<GTlsCertificateFlags>(resourceError.tlsErrors()), resourceError.certificate()); + } else + webkitWebViewLoadFailed(m_webView, WEBKIT_LOAD_STARTED, resourceError.failingURL().string().utf8().data(), error.get()); + } + + void didCommitLoadForFrame(WebPageProxy&, WebFrameProxy& frame, API::Navigation*, API::Object* /* userData */) override + { + if (!frame.isMainFrame()) + return; + webkitWebViewLoadChanged(m_webView, WEBKIT_LOAD_COMMITTED); + } + + void didFinishLoadForFrame(WebPageProxy&, WebFrameProxy& frame, API::Navigation*, API::Object* /* userData */) override + { + if (!frame.isMainFrame()) + return; + webkitWebViewLoadChanged(m_webView, WEBKIT_LOAD_FINISHED); + } + + void didFailLoadWithErrorForFrame(WebPageProxy&, WebFrameProxy& frame, API::Navigation*, const ResourceError& resourceError, API::Object* /* userData */) override + { + if (!frame.isMainFrame()) + return; + GUniquePtr<GError> error(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()), + toWebKitError(resourceError.errorCode()), resourceError.localizedDescription().utf8().data())); + webkitWebViewLoadFailed(m_webView, WEBKIT_LOAD_COMMITTED, resourceError.failingURL().string().utf8().data(), error.get()); + } + + void didDisplayInsecureContentForFrame(WebPageProxy&, WebFrameProxy&, API::Object* /* userData */) override + { + webkitWebViewInsecureContentDetected(m_webView, WEBKIT_INSECURE_CONTENT_DISPLAYED); + } + + void didRunInsecureContentForFrame(WebPageProxy&, WebFrameProxy&, API::Object* /* userData */) override + { + webkitWebViewInsecureContentDetected(m_webView, WEBKIT_INSECURE_CONTENT_RUN); + } + + void didChangeBackForwardList(WebPageProxy&, WebBackForwardListItem* addedItem, Vector<RefPtr<WebBackForwardListItem>> removedItems) override + { + webkitBackForwardListChanged(webkit_web_view_get_back_forward_list(m_webView), addedItem, removedItems); + } + + void didReceiveAuthenticationChallengeInFrame(WebPageProxy&, WebFrameProxy&, AuthenticationChallengeProxy* authenticationChallenge) override + { + webkitWebViewHandleAuthenticationChallenge(m_webView, authenticationChallenge); + } + + void processDidCrash(WebPageProxy&) override + { + webkitWebViewWebProcessCrashed(m_webView); + } + + WebKitWebView* m_webView; +}; void attachLoaderClientToView(WebKitWebView* webView) { - WKPageLoaderClientV3 wkLoaderClient = { - { - 3, // version - webView, // clientInfo - }, - didStartProvisionalLoadForFrame, - didReceiveServerRedirectForProvisionalLoadForFrame, - didFailProvisionalLoadWithErrorForFrame, - didCommitLoadForFrame, - 0, // didFinishDocumentLoadForFrame - didFinishLoadForFrame, - didFailLoadWithErrorForFrame, - didSameDocumentNavigationForFrame, - didReceiveTitleForFrame, - 0, // didFirstLayoutForFrame - 0, // didFirstVisuallyNonEmptyLayoutForFrame - 0, // didRemoveFrameFromHierarchy - didDisplayInsecureContentForFrame, - didRunInsecureContentForFrame, - 0, // canAuthenticateAgainstProtectionSpaceInFrame - didReceiveAuthenticationChallengeInFrame, - didChangeProgress, // didStartProgress - didChangeProgress, - didChangeProgress, // didFinishProgress - 0, // didBecomeUnresponsive - 0, // didBecomeResponsive - processDidCrash, - didChangeBackForwardList, - 0, // shouldGoToBackForwardListItem - 0, // didFailToInitializePlugin - 0, // didDetectXSSForFrame - 0, // didFirstVisuallyNonEmptyLayoutForFrame - 0, // willGoToBackForwardListItem - 0, // interactionOccurredWhileProcessUnresponsive - 0, // pluginDidFail_deprecatedForUseWithV1 - 0, // didReceiveIntentForFrame - 0, // registerIntentServiceForFrame - 0, // didLayout - 0, // pluginLoadPolicy_deprecatedForUseWithV2 - 0, // pluginDidFail - 0, // pluginLoadPolicy - }; - WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); - WKPageSetPageLoaderClient(wkPage, &wkLoaderClient.base); + WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)); + page->setLoaderClient(std::make_unique<LoaderClient>(webView)); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitMimeInfo.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitMimeInfo.cpp index 2282ede37..af61dc69a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitMimeInfo.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitMimeInfo.cpp @@ -21,7 +21,7 @@ #include "WebKitMimeInfo.h" #include "WebKitMimeInfoPrivate.h" -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> struct _WebKitMimeInfo { @@ -42,7 +42,7 @@ G_DEFINE_BOXED_TYPE(WebKitMimeInfo, webkit_mime_info, webkit_mime_info_ref, webk WebKitMimeInfo* webkitMimeInfoCreate(const WebCore::MimeClassInfo& mimeInfo) { - WebKitMimeInfo* info = g_slice_new(WebKitMimeInfo); + WebKitMimeInfo* info = static_cast<WebKitMimeInfo*>(fastMalloc(sizeof(WebKitMimeInfo))); new (info) WebKitMimeInfo(mimeInfo); return info; } @@ -75,7 +75,7 @@ void webkit_mime_info_unref(WebKitMimeInfo* info) { if (g_atomic_int_dec_and_test(&info->referenceCount)) { info->~WebKitMimeInfo(); - g_slice_free(WebKitMimeInfo, info); + fastFree(info); } } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationAction.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationAction.cpp new file mode 100644 index 000000000..bcce8ba42 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationAction.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitNavigationAction.h" + +#include "WebKitNavigationActionPrivate.h" +#include <gdk/gdk.h> +#include <wtf/glib/GRefPtr.h> + +using namespace WebKit; + +G_DEFINE_BOXED_TYPE(WebKitNavigationAction, webkit_navigation_action, webkit_navigation_action_copy, webkit_navigation_action_free) + +WebKitNavigationAction* webkitNavigationActionCreate(WebKitURIRequest* request, const NavigationActionData& navigationActionData) +{ + WebKitNavigationAction* navigation = static_cast<WebKitNavigationAction*>(fastZeroedMalloc(sizeof(WebKitNavigationAction))); + new (navigation) WebKitNavigationAction(request, navigationActionData); + return navigation; +} + +/** + * webkit_navigation_action_copy: + * @navigation: a #WebKitNavigationAction + * + * Make a copy of @navigation. + * + * Returns: (transfer full): A copy of passed in #WebKitNavigationAction + * + * Since: 2.6 + */ +WebKitNavigationAction* webkit_navigation_action_copy(WebKitNavigationAction* navigation) +{ + g_return_val_if_fail(navigation, nullptr); + + WebKitNavigationAction* copy = static_cast<WebKitNavigationAction*>(fastZeroedMalloc(sizeof(WebKitNavigationAction))); + new (copy) WebKitNavigationAction(navigation); + return copy; +} + +/** + * webkit_navigation_action_free: + * @navigation: a #WebKitNavigationAction + * + * Free the #WebKitNavigationAction + * + * Since: 2.6 + */ +void webkit_navigation_action_free(WebKitNavigationAction* navigation) +{ + g_return_if_fail(navigation); + + navigation->~WebKitNavigationAction(); + fastFree(navigation); +} + +/** + * webkit_navigation_action_get_navigation_type: + * @navigation: a #WebKitNavigationAction + * + * Return the type of action that triggered the navigation. + * + * Returns: a #WebKitNavigationType + * + * Since: 2.6 + */ +WebKitNavigationType webkit_navigation_action_get_navigation_type(WebKitNavigationAction* navigation) +{ + g_return_val_if_fail(navigation, WEBKIT_NAVIGATION_TYPE_OTHER); + return navigation->type; +} + +/** + * webkit_navigation_action_get_mouse_button: + * @navigation: a #WebKitNavigationAction + * + * Return the number of the mouse button that triggered the navigation, or 0 if + * the navigation was not started by a mouse event. + * + * Returns: the mouse button number or 0 + * + * Since: 2.6 + */ +unsigned webkit_navigation_action_get_mouse_button(WebKitNavigationAction* navigation) +{ + g_return_val_if_fail(navigation, 0); + return navigation->mouseButton; +} + +/** + * webkit_navigation_action_get_modifiers: + * @navigation: a #WebKitNavigationAction + * + * Return a bitmask of #GdkModifierType values describing the modifier keys that were in effect + * when the navigation was requested + * + * Returns: the modifier keys + * + * Since: 2.6 + */ +unsigned webkit_navigation_action_get_modifiers(WebKitNavigationAction* navigation) +{ + g_return_val_if_fail(navigation, 0); + return navigation->modifiers; +} + +/** + * webkit_navigation_action_get_request: + * @navigation: a #WebKitNavigationAction + * + * Return the navigation #WebKitURIRequest + * + * Returns: (transfer none): a #WebKitURIRequest + * + * Since: 2.6 + */ +WebKitURIRequest* webkit_navigation_action_get_request(WebKitNavigationAction* navigation) +{ + g_return_val_if_fail(navigation, nullptr); + return navigation->request.get(); +} + +/** + * webkit_navigation_action_is_user_gesture: + * @navigation: a #WebKitNavigationAction + * + * Return whether the navigation was triggered by a user gesture like a mouse click. + * + * Returns: whether navigation action is a user gesture + * + * Since: 2.6 + */ +gboolean webkit_navigation_action_is_user_gesture(WebKitNavigationAction* navigation) +{ + g_return_val_if_fail(navigation, FALSE); + return navigation->isUserGesture; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationAction.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationAction.h new file mode 100644 index 000000000..ae95586bc --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationAction.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitNavigationAction_h +#define WebKitNavigationAction_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitURIRequest.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_NAVIGATION_ACTION (webkit_navigation_action_get_type()) + +/** + * WebKitNavigationType: + * @WEBKIT_NAVIGATION_TYPE_LINK_CLICKED: The navigation was triggered by clicking a link. + * @WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED: The navigation was triggered by submitting a form. + * @WEBKIT_NAVIGATION_TYPE_BACK_FORWARD: The navigation was triggered by navigating forward or backward. + * @WEBKIT_NAVIGATION_TYPE_RELOAD: The navigation was triggered by reloading. + * @WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED: The navigation was triggered by resubmitting a form. + * @WEBKIT_NAVIGATION_TYPE_OTHER: The navigation was triggered by some other action. + * + * Enum values used to denote the various navigation types. + */ +typedef enum { + WEBKIT_NAVIGATION_TYPE_LINK_CLICKED, + WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED, + WEBKIT_NAVIGATION_TYPE_BACK_FORWARD, + WEBKIT_NAVIGATION_TYPE_RELOAD, + WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED, + WEBKIT_NAVIGATION_TYPE_OTHER +} WebKitNavigationType; + +typedef struct _WebKitNavigationAction WebKitNavigationAction; + + +WEBKIT_API GType +webkit_navigation_action_get_type (void); + +WEBKIT_API WebKitNavigationAction * +webkit_navigation_action_copy (WebKitNavigationAction *navigation); + +WEBKIT_API void +webkit_navigation_action_free (WebKitNavigationAction *navigation); + +WEBKIT_API WebKitNavigationType +webkit_navigation_action_get_navigation_type (WebKitNavigationAction *navigation); + +WEBKIT_API guint +webkit_navigation_action_get_mouse_button (WebKitNavigationAction *navigation); + +WEBKIT_API guint +webkit_navigation_action_get_modifiers (WebKitNavigationAction *navigation); + +WEBKIT_API WebKitURIRequest * +webkit_navigation_action_get_request (WebKitNavigationAction *navigation); + +WEBKIT_API gboolean +webkit_navigation_action_is_user_gesture (WebKitNavigationAction *navigation); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationActionPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationActionPrivate.h new file mode 100644 index 000000000..f426404cb --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationActionPrivate.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitNavigationActionPrivate_h +#define WebKitNavigationActionPrivate_h + +#include "NavigationActionData.h" +#include "WebKitNavigationAction.h" +#include "WebKitPrivate.h" + +struct _WebKitNavigationAction { + _WebKitNavigationAction(WebKitURIRequest* uriRequest, const WebKit::NavigationActionData& navigationActionData) + : type(toWebKitNavigationType(navigationActionData.navigationType)) + , mouseButton(toWebKitMouseButton(navigationActionData.mouseButton)) + , modifiers(toGdkModifiers(navigationActionData.modifiers)) + , isUserGesture(navigationActionData.userGestureTokenIdentifier) + , request(uriRequest) + { + } + + _WebKitNavigationAction(WebKitNavigationAction* navigation) + : type(navigation->type) + , mouseButton(navigation->mouseButton) + , modifiers(navigation->modifiers) + , isUserGesture(navigation->isUserGesture) + , request(navigation->request) + { + } + + WebKitNavigationType type; + unsigned mouseButton; + unsigned modifiers; + bool isUserGesture : 1; + GRefPtr<WebKitURIRequest> request; +}; + +WebKitNavigationAction* webkitNavigationActionCreate(WebKitURIRequest*, const WebKit::NavigationActionData&); + +#endif // WebKitNavigationActionPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp index f03446bab..e5769723c 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp @@ -20,13 +20,13 @@ #include "config.h" #include "WebKitNavigationPolicyDecision.h" -#include "APIURLRequest.h" -#include "WebEvent.h" #include "WebKitEnumTypes.h" +#include "WebKitNavigationActionPrivate.h" +#include "WebKitNavigationPolicyDecisionPrivate.h" #include "WebKitPolicyDecisionPrivate.h" #include "WebKitURIRequestPrivate.h" #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -44,10 +44,12 @@ using namespace WebCore; */ struct _WebKitNavigationPolicyDecisionPrivate { - WebKitNavigationType navigationType; - unsigned modifiers; - unsigned mouseButton; - GRefPtr<WebKitURIRequest> request; + ~_WebKitNavigationPolicyDecisionPrivate() + { + webkit_navigation_action_free(navigationAction); + } + + WebKitNavigationAction* navigationAction; CString frameName; }; @@ -55,6 +57,7 @@ WEBKIT_DEFINE_TYPE(WebKitNavigationPolicyDecision, webkit_navigation_policy_deci enum { PROP_0, + PROP_NAVIGATION_ACTION, PROP_NAVIGATION_TYPE, PROP_MOUSE_BUTTON, PROP_MODIFIERS, @@ -66,17 +69,20 @@ static void webkitNavigationPolicyDecisionGetProperty(GObject* object, guint pro { WebKitNavigationPolicyDecision* decision = WEBKIT_NAVIGATION_POLICY_DECISION(object); switch (propId) { + case PROP_NAVIGATION_ACTION: + g_value_set_boxed(value, webkit_navigation_policy_decision_get_navigation_action(decision)); + break; case PROP_NAVIGATION_TYPE: - g_value_set_enum(value, webkit_navigation_policy_decision_get_navigation_type(decision)); + g_value_set_enum(value, webkit_navigation_action_get_navigation_type(decision->priv->navigationAction)); break; case PROP_MOUSE_BUTTON: - g_value_set_enum(value, webkit_navigation_policy_decision_get_mouse_button(decision)); + g_value_set_enum(value, webkit_navigation_action_get_mouse_button(decision->priv->navigationAction)); break; case PROP_MODIFIERS: - g_value_set_uint(value, webkit_navigation_policy_decision_get_modifiers(decision)); + g_value_set_uint(value, webkit_navigation_action_get_modifiers(decision->priv->navigationAction)); break; case PROP_REQUEST: - g_value_set_object(value, webkit_navigation_policy_decision_get_request(decision)); + g_value_set_object(value, webkit_navigation_action_get_request(decision->priv->navigationAction)); break; case PROP_FRAME_NAME: g_value_set_string(value, webkit_navigation_policy_decision_get_frame_name(decision)); @@ -93,11 +99,30 @@ static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyD objectClass->get_property = webkitNavigationPolicyDecisionGetProperty; /** + * WebKitNavigationPolicyDecision:navigation-action: + * + * The #WebKitNavigationAction that triggered this policy decision. + * + * Since: 2.6 + */ + g_object_class_install_property( + objectClass, + PROP_NAVIGATION_ACTION, + g_param_spec_boxed( + "navigation-action", + _("Navigation action"), + _("The WebKitNavigationAction triggering this decision"), + WEBKIT_TYPE_NAVIGATION_ACTION, + WEBKIT_PARAM_READABLE)); + + /** * WebKitNavigationPolicyDecision:navigation-type: * * The type of navigation that triggered this policy decision. This is * useful for enacting different policies depending on what type of user * action caused the navigation. + * + * Deprecated: 2.6: Use #WebKitNavigationPolicyDecision:navigation-action instead */ g_object_class_install_property(objectClass, PROP_NAVIGATION_TYPE, @@ -116,6 +141,8 @@ static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyD * of the button triggering that event. The button numbers match those from GDK. * If the navigation was not triggered by a mouse event, the value of this * property will be 0. + * + * Deprecated: 2.6: Use #WebKitNavigationPolicyDecision:navigation-action instead */ g_object_class_install_property(objectClass, PROP_MOUSE_BUTTON, @@ -133,6 +160,8 @@ static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyD * #GdkModifierType values describing the modifiers used for that click. * If the navigation was not triggered by a mouse event or no modifiers * were active, the value of this property will be zero. + * + * Deprecated: 2.6: Use #WebKitNavigationPolicyDecision:navigation-action instead */ g_object_class_install_property(objectClass, PROP_MODIFIERS, @@ -147,6 +176,8 @@ static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyD * * This property contains the #WebKitURIRequest associated with this * navigation. + * + * Deprecated: 2.6: Use #WebKitNavigationPolicyDecision:navigation-action instead */ g_object_class_install_property(objectClass, PROP_REQUEST, @@ -174,17 +205,35 @@ static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyD } /** + * webkit_navigation_policy_decision_get_navigation_action: + * @decision: a #WebKitNavigationPolicyDecision + * + * Gets the value of the #WebKitNavigationPolicyDecision:navigation-action property. + * + * Returns: (transfer none): The #WebKitNavigationAction triggering this policy decision. + * + * Since: 2.6 + */ +WebKitNavigationAction* webkit_navigation_policy_decision_get_navigation_action(WebKitNavigationPolicyDecision* decision) +{ + g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), nullptr); + return decision->priv->navigationAction; +} + +/** * webkit_navigation_policy_decision_get_navigation_type: * @decision: a #WebKitNavigationPolicyDecision * * Gets the value of the #WebKitNavigationPolicyDecision:navigation-type property. * * Returns: The type of navigation triggering this policy decision. + * + * Deprecated: 2.6: Use webkit_navigation_policy_decision_get_navigation_action() instead. */ WebKitNavigationType webkit_navigation_policy_decision_get_navigation_type(WebKitNavigationPolicyDecision* decision) { g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), WEBKIT_NAVIGATION_TYPE_OTHER); - return decision->priv->navigationType; + return webkit_navigation_action_get_navigation_type(decision->priv->navigationAction); } /** @@ -194,11 +243,13 @@ WebKitNavigationType webkit_navigation_policy_decision_get_navigation_type(WebKi * Gets the value of the #WebKitNavigationPolicyDecision:mouse-button property. * * Returns: The mouse button used if this decision was triggered by a mouse event or 0 otherwise + * + * Deprecated: 2.6: Use webkit_navigation_policy_decision_get_navigation_action() instead. */ guint webkit_navigation_policy_decision_get_mouse_button(WebKitNavigationPolicyDecision* decision) { g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0); - return decision->priv->mouseButton; + return webkit_navigation_action_get_mouse_button(decision->priv->navigationAction); } /** @@ -208,11 +259,13 @@ guint webkit_navigation_policy_decision_get_mouse_button(WebKitNavigationPolicyD * Gets the value of the #WebKitNavigationPolicyDecision:modifiers property. * * Returns: The modifiers active if this decision was triggered by a mouse event + * + * Deprecated: 2.6: Use webkit_navigation_policy_decision_get_navigation_action() instead. */ unsigned webkit_navigation_policy_decision_get_modifiers(WebKitNavigationPolicyDecision* decision) { g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0); - return decision->priv->modifiers; + return webkit_navigation_action_get_modifiers(decision->priv->navigationAction); } /** @@ -222,11 +275,13 @@ unsigned webkit_navigation_policy_decision_get_modifiers(WebKitNavigationPolicyD * Gets the value of the #WebKitNavigationPolicyDecision:request property. * * Returns: (transfer none): The URI request that is associated with this navigation + * + * Deprecated: 2.6: Use webkit_navigation_policy_decision_get_navigation_action() instead. */ WebKitURIRequest* webkit_navigation_policy_decision_get_request(WebKitNavigationPolicyDecision* decision) { - g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0); - return decision->priv->request.get(); + g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), nullptr); + return webkit_navigation_action_get_request(decision->priv->navigationAction); } /** @@ -243,21 +298,19 @@ const char* webkit_navigation_policy_decision_get_frame_name(WebKitNavigationPol return decision->priv->frameName.data(); } -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_LINK_CLICKED, NavigationTypeLinkClicked); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED, NavigationTypeFormSubmitted); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_BACK_FORWARD, NavigationTypeBackForward); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_RELOAD, NavigationTypeReload); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED, NavigationTypeFormResubmitted); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_OTHER, NavigationTypeOther); +WebKitPolicyDecision* webkitNavigationPolicyDecisionCreate(const NavigationActionData& navigationActionData, const ResourceRequest& request, WebFramePolicyListenerProxy* listener) +{ + WebKitNavigationPolicyDecision* navigationDecision = WEBKIT_NAVIGATION_POLICY_DECISION(g_object_new(WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, nullptr)); + GRefPtr<WebKitURIRequest> uriRequest = adoptGRef(webkitURIRequestCreateForResourceRequest(request)); + navigationDecision->priv->navigationAction = webkitNavigationActionCreate(uriRequest.get(), navigationActionData); + WebKitPolicyDecision* decision = WEBKIT_POLICY_DECISION(navigationDecision); + webkitPolicyDecisionSetListener(decision, listener); + return decision; +} -WebKitNavigationPolicyDecision* webkitNavigationPolicyDecisionCreate(WebKitNavigationType navigationType, unsigned mouseButton, unsigned modifiers, API::URLRequest* request, const char* frameName, WebFramePolicyListenerProxy* listener) +WebKitPolicyDecision* webkitNewWindowPolicyDecisionCreate(const NavigationActionData& navigationActionData, const ResourceRequest& request, const String& frameName, WebFramePolicyListenerProxy* listener) { - WebKitNavigationPolicyDecision* decision = WEBKIT_NAVIGATION_POLICY_DECISION(g_object_new(WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, NULL)); - decision->priv->navigationType = navigationType; - decision->priv->mouseButton = mouseButton; - decision->priv->modifiers = modifiers; - decision->priv->request = adoptGRef(webkitURIRequestCreateForResourceRequest(request->resourceRequest())); - decision->priv->frameName = frameName; - webkitPolicyDecisionSetListener(WEBKIT_POLICY_DECISION(decision), listener); + WebKitPolicyDecision* decision = webkitNavigationPolicyDecisionCreate(navigationActionData, request, listener); + WEBKIT_NAVIGATION_POLICY_DECISION(decision)->priv->frameName = frameName.utf8().data(); return decision; } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h index 751397731..0d9fb261a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h @@ -26,31 +26,12 @@ #include <glib-object.h> #include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitNavigationAction.h> #include <webkit2/WebKitPolicyDecision.h> #include <webkit2/WebKitURIRequest.h> G_BEGIN_DECLS -/** - * WebKitNavigationType: - * @WEBKIT_NAVIGATION_TYPE_LINK_CLICKED: The navigation was triggered by clicking a link. - * @WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED: The navigation was triggered by submitting a form. - * @WEBKIT_NAVIGATION_TYPE_BACK_FORWARD: The navigation was triggered by navigating forward or backward. - * @WEBKIT_NAVIGATION_TYPE_RELOAD: The navigation was triggered by reloading. - * @WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED: The navigation was triggered by resubmitting a form. - * @WEBKIT_NAVIGATION_TYPE_OTHER: The navigation was triggered by some other action. - * - * Enum values used to denote the various navigation types. - */ -typedef enum { - WEBKIT_NAVIGATION_TYPE_LINK_CLICKED, - WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED, - WEBKIT_NAVIGATION_TYPE_BACK_FORWARD, - WEBKIT_NAVIGATION_TYPE_RELOAD, - WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED, - WEBKIT_NAVIGATION_TYPE_OTHER, -} WebKitNavigationType; - #define WEBKIT_TYPE_NAVIGATION_POLICY_DECISION (webkit_navigation_policy_decision_get_type()) #define WEBKIT_NAVIGATION_POLICY_DECISION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, WebKitNavigationPolicyDecision)) #define WEBKIT_NAVIGATION_POLICY_DECISION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, WebKitNavigationPolicyDecisionClass)) @@ -81,16 +62,24 @@ struct _WebKitNavigationPolicyDecisionClass { WEBKIT_API GType webkit_navigation_policy_decision_get_type (void); -WEBKIT_API WebKitNavigationType -webkit_navigation_policy_decision_get_navigation_type (WebKitNavigationPolicyDecision *decision); -WEBKIT_API guint -webkit_navigation_policy_decision_get_mouse_button (WebKitNavigationPolicyDecision *decision); -WEBKIT_API guint -webkit_navigation_policy_decision_get_modifiers (WebKitNavigationPolicyDecision *decision); -WEBKIT_API WebKitURIRequest * -webkit_navigation_policy_decision_get_request (WebKitNavigationPolicyDecision *decision); +WEBKIT_API WebKitNavigationAction * +webkit_navigation_policy_decision_get_navigation_action (WebKitNavigationPolicyDecision *decision); + +WEBKIT_DEPRECATED_FOR(webkit_navigation_policy_decision_get_navigation_action) WebKitNavigationType +webkit_navigation_policy_decision_get_navigation_type (WebKitNavigationPolicyDecision *decision); + +WEBKIT_DEPRECATED_FOR(webkit_navigation_policy_decision_get_navigation_action) guint +webkit_navigation_policy_decision_get_mouse_button (WebKitNavigationPolicyDecision *decision); + +WEBKIT_DEPRECATED_FOR(webkit_navigation_policy_decision_get_navigation_action) guint +webkit_navigation_policy_decision_get_modifiers (WebKitNavigationPolicyDecision *decision); + +WEBKIT_DEPRECATED_FOR(webkit_navigation_policy_decision_get_navigation_action) WebKitURIRequest * +webkit_navigation_policy_decision_get_request (WebKitNavigationPolicyDecision *decision); + WEBKIT_API const gchar * -webkit_navigation_policy_decision_get_frame_name (WebKitNavigationPolicyDecision *decision); +webkit_navigation_policy_decision_get_frame_name (WebKitNavigationPolicyDecision *decision); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h index 84ee827cd..9d94ee00e 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h @@ -20,9 +20,11 @@ #ifndef WebKitNavigationPolicyDecisionPrivate_h #define WebKitNavigationPolicyDecisionPrivate_h +#include "NavigationActionData.h" #include "WebKitNavigationPolicyDecision.h" #include "WebKitPrivate.h" -WebKitNavigationPolicyDecision* webkitNavigationPolicyDecisionCreate(WebKitNavigationType, unsigned mouseButton, unsigned modifiers, API::URLRequest*, const char* frameName, WebKit::WebFramePolicyListenerProxy*); +WebKitPolicyDecision* webkitNavigationPolicyDecisionCreate(const WebKit::NavigationActionData&, const WebCore::ResourceRequest&, WebKit::WebFramePolicyListenerProxy*); +WebKitPolicyDecision* webkitNewWindowPolicyDecisionCreate(const WebKit::NavigationActionData&, const WebCore::ResourceRequest&, const String& frameName, WebKit::WebFramePolicyListenerProxy*); #endif // WebKitNavigationPolicyDecisionPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.cpp new file mode 100644 index 000000000..11cba3357 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitNetworkProxySettings.h" + +#include "WebKitNetworkProxySettingsPrivate.h" +#include <WebCore/SoupNetworkProxySettings.h> +#include <wtf/text/WTFString.h> + +using namespace WebKit; +using namespace WebCore; + +/** + * SECTION: WebKitNetworkProxySettings + * @Short_description: Network Proxy Settings + * @Title: WebKitNetworkProxySettings + * @See_also: #WebKitWebContext + * + * WebKitNetworkProxySettings can be used to provide a custom proxy configuration + * to a #WebKitWebContext. You need to call webkit_web_context_set_network_proxy_settings() + * with %WEBKIT_NETWORK_PROXY_MODE_CUSTOM and a WebKitNetworkProxySettings. + * + * Since: 2.16 + */ +struct _WebKitNetworkProxySettings { + _WebKitNetworkProxySettings() + : settings(SoupNetworkProxySettings::Mode::Custom) + { + } + + explicit _WebKitNetworkProxySettings(const SoupNetworkProxySettings& otherSettings) + : settings(otherSettings) + { + } + + SoupNetworkProxySettings settings; +}; + +G_DEFINE_BOXED_TYPE(WebKitNetworkProxySettings, webkit_network_proxy_settings, webkit_network_proxy_settings_copy, webkit_network_proxy_settings_free) + +const SoupNetworkProxySettings& webkitNetworkProxySettingsGetNetworkProxySettings(WebKitNetworkProxySettings* proxySettings) +{ + ASSERT(proxySettings); + return proxySettings->settings; +} + +/** + * webkit_network_proxy_settings_new: + * @default_proxy_uri: (allow-none): the default proxy URI to use, or %NULL. + * @ignore_hosts: (allow-none): an optional list of hosts/IP addresses to not use a proxy for. + * + * Create a new #WebKitNetworkProxySettings with the given @default_proxy_uri and @ignore_hosts. + * + * The default proxy URI will be used for any URI that doesn't match @ignore_hosts, and doesn't match any + * of the schemes added with webkit_network_proxy_settings_add_proxy_for_scheme(). + * If @default_proxy_uri starts with "socks://", it will be treated as referring to all three of the + * socks5, socks4a, and socks4 proxy types. + * + * @ignore_hosts is a list of hostnames and IP addresses that the resolver should allow direct connections to. + * Entries can be in one of 4 formats: + * <itemizedlist> + * <listitem><para> + * A hostname, such as "example.com", ".example.com", or "*.example.com", any of which match "example.com" or + * any subdomain of it. + * </para></listitem> + * <listitem><para> + * An IPv4 or IPv6 address, such as "192.168.1.1", which matches only that address. + * </para></listitem> + * <listitem><para> + * A hostname or IP address followed by a port, such as "example.com:80", which matches whatever the hostname or IP + * address would match, but only for URLs with the (explicitly) indicated port. In the case of an IPv6 address, the address + * part must appear in brackets: "[::1]:443" + * </para></listitem> + * <listitem><para> + * An IP address range, given by a base address and prefix length, such as "fe80::/10", which matches any address in that range. + * </para></listitem> + * </itemizedlist> + * + * Note that when dealing with Unicode hostnames, the matching is done against the ASCII form of the name. + * Also note that hostname exclusions apply only to connections made to hosts identified by name, and IP address exclusions apply only + * to connections made to hosts identified by address. That is, if example.com has an address of 192.168.1.1, and @ignore_hosts + * contains only "192.168.1.1", then a connection to "example.com" will use the proxy, and a connection to 192.168.1.1" will not. + * + * Returns: (transfer full): A new #WebKitNetworkProxySettings. + * + * Since: 2.16 + */ +WebKitNetworkProxySettings* webkit_network_proxy_settings_new(const char* defaultProxyURI, const char* const* ignoreHosts) +{ + WebKitNetworkProxySettings* proxySettings = static_cast<WebKitNetworkProxySettings*>(fastMalloc(sizeof(WebKitNetworkProxySettings))); + new (proxySettings) WebKitNetworkProxySettings; + if (defaultProxyURI) + proxySettings->settings.defaultProxyURL = defaultProxyURI; + if (ignoreHosts) + proxySettings->settings.ignoreHosts.reset(g_strdupv(const_cast<char**>(ignoreHosts))); + return proxySettings; +} + +/** + * webkit_network_proxy_settings_copy: + * @proxy_settings: a #WebKitNetworkProxySettings + * + * Make a copy of the #WebKitNetworkProxySettings. + * + * Returns: (transfer full): A copy of passed in #WebKitNetworkProxySettings + * + * Since: 2.16 + */ +WebKitNetworkProxySettings* webkit_network_proxy_settings_copy(WebKitNetworkProxySettings* proxySettings) +{ + g_return_val_if_fail(proxySettings, nullptr); + + WebKitNetworkProxySettings* copy = static_cast<WebKitNetworkProxySettings*>(fastMalloc(sizeof(WebKitNetworkProxySettings))); + new (copy) WebKitNetworkProxySettings(webkitNetworkProxySettingsGetNetworkProxySettings(proxySettings)); + return copy; +} + +/** + * webkit_network_proxy_settings_free: + * @proxy_settings: A #WebKitNetworkProxySettings + * + * Free the #WebKitNetworkProxySettings. + * + * Since: 2.16 + */ +void webkit_network_proxy_settings_free(WebKitNetworkProxySettings* proxySettings) +{ + g_return_if_fail(proxySettings); + + proxySettings->~WebKitNetworkProxySettings(); + fastFree(proxySettings); +} + +/** + * webkit_network_proxy_settings_add_proxy_for_scheme: + * @proxy_settings: a #WebKitNetworkProxySettings + * @scheme: the URI scheme to add a proxy for + * @proxy_uri: the proxy URI to use for @uri_scheme + * + * Adds a URI-scheme-specific proxy. URIs whose scheme matches @uri_scheme will be proxied via @proxy_uri. + * As with the default proxy URI, if @proxy_uri starts with "socks://", it will be treated as referring to + * all three of the socks5, socks4a, and socks4 proxy types. + * + * Since: 2.16 + */ +void webkit_network_proxy_settings_add_proxy_for_scheme(WebKitNetworkProxySettings* proxySettings, const char* scheme, const char* proxyURI) +{ + g_return_if_fail(proxySettings); + g_return_if_fail(scheme); + g_return_if_fail(proxyURI); + + proxySettings->settings.proxyMap.add(scheme, proxyURI); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.h new file mode 100644 index 000000000..00c2b39f3 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitNetworkProxySettings_h +#define WebKitNetworkProxySettings_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_NETWORK_NETWORK_PROXY_SETTINGS (webkit_network_proxy_settings_get_type()) + +typedef struct _WebKitNetworkProxySettings WebKitNetworkProxySettings; + +WEBKIT_API GType +webkit_network_proxy_settings_get_type (void); + +WEBKIT_API WebKitNetworkProxySettings * +webkit_network_proxy_settings_new (const gchar *default_proxy_uri, + const gchar* const *ignore_hosts); + +WEBKIT_API WebKitNetworkProxySettings * +webkit_network_proxy_settings_copy (WebKitNetworkProxySettings *proxy_settings); + +WEBKIT_API void +webkit_network_proxy_settings_free (WebKitNetworkProxySettings *proxy_settings); + +WEBKIT_API void +webkit_network_proxy_settings_add_proxy_for_scheme (WebKitNetworkProxySettings *proxy_settings, + const gchar *scheme, + const gchar *proxy_uri); + +G_END_DECLS + +#endif /* WebKitNetworkProxySettings_h */ diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettingsPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettingsPrivate.h new file mode 100644 index 000000000..9691226f2 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettingsPrivate.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "WebKitNetworkProxySettings.h" +#include "WebKitPrivate.h" +#include <WebCore/SoupNetworkProxySettings.h> + +const WebCore::SoupNetworkProxySettings& webkitNetworkProxySettingsGetNetworkProxySettings(WebKitNetworkProxySettings*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotification.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNotification.cpp new file mode 100644 index 000000000..3d1c4949c --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotification.cpp @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2014 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitNotification.h" + +#include "WebKitNotificationPrivate.h" +#include "WebKitPrivate.h" +#include "WebNotification.h" +#include <glib/gi18n-lib.h> +#include <wtf/text/CString.h> + +/** + * SECTION: WebKitNotification + * @Short_description: Object used to hold information about a notification that should be shown to the user. + * @Title: WebKitNotification + * + * Since: 2.8 + */ + +enum { + PROP_0, + + PROP_ID, + PROP_TITLE, + PROP_BODY, + PROP_TAG +}; + +enum { + CLOSED, + CLICKED, + + LAST_SIGNAL +}; + +struct _WebKitNotificationPrivate { + CString title; + CString body; + CString tag; + guint64 id; + + WebKitWebView* webView; +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +WEBKIT_DEFINE_TYPE(WebKitNotification, webkit_notification, G_TYPE_OBJECT) + +static void webkitNotificationGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) +{ + WebKitNotification* notification = WEBKIT_NOTIFICATION(object); + + switch (propId) { + case PROP_ID: + g_value_set_uint64(value, webkit_notification_get_id(notification)); + break; + case PROP_TITLE: + g_value_set_string(value, webkit_notification_get_title(notification)); + break; + case PROP_BODY: + g_value_set_string(value, webkit_notification_get_body(notification)); + break; + case PROP_TAG: + g_value_set_string(value, webkit_notification_get_tag(notification)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkit_notification_class_init(WebKitNotificationClass* notificationClass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(notificationClass); + objectClass->get_property = webkitNotificationGetProperty; + + /** + * WebKitNotification:id: + * + * The unique id for the notification. + * + * Since: 2.8 + */ + g_object_class_install_property(objectClass, + PROP_ID, + g_param_spec_uint64("id", + _("ID"), + _("The unique id for the notification"), + 0, G_MAXUINT64, 0, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitNotification:title: + * + * The title for the notification. + * + * Since: 2.8 + */ + g_object_class_install_property(objectClass, + PROP_TITLE, + g_param_spec_string("title", + _("Title"), + _("The title for the notification"), + nullptr, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitNotification:body: + * + * The body for the notification. + * + * Since: 2.8 + */ + g_object_class_install_property(objectClass, + PROP_BODY, + g_param_spec_string("body", + _("Body"), + _("The body for the notification"), + nullptr, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitNotification:tag: + * + * The tag identifier for the notification. + * + * Since: 2.16 + */ + g_object_class_install_property(objectClass, + PROP_TAG, + g_param_spec_string("tag", + _("Tag"), + _("The tag identifier for the notification"), + nullptr, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitNotification::closed: + * @notification: the #WebKitNotification on which the signal is emitted + * + * Emitted when a notification has been withdrawn. + * + * The default handler will close the notification using libnotify, if built with + * support for it. + * + * Since: 2.8 + */ + signals[CLOSED] = + g_signal_new( + "closed", + G_TYPE_FROM_CLASS(notificationClass), + G_SIGNAL_RUN_LAST, + 0, 0, + nullptr, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * WebKitNotification::clicked: + * @notification: the #WebKitNotification on which the signal is emitted + * + * Emitted when a notification has been clicked. See webkit_notification_clicked(). + * + * Since: 2.12 + */ + signals[CLICKED] = + g_signal_new( + "clicked", + G_TYPE_FROM_CLASS(notificationClass), + G_SIGNAL_RUN_LAST, + 0, 0, + nullptr, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +WebKitNotification* webkitNotificationCreate(WebKitWebView* webView, const WebKit::WebNotification& webNotification) +{ + WebKitNotification* notification = WEBKIT_NOTIFICATION(g_object_new(WEBKIT_TYPE_NOTIFICATION, nullptr)); + notification->priv->id = webNotification.notificationID(); + notification->priv->title = webNotification.title().utf8(); + notification->priv->body = webNotification.body().utf8(); + notification->priv->tag = webNotification.tag().utf8(); + notification->priv->webView = webView; + return notification; +} + +WebKitWebView* webkitNotificationGetWebView(WebKitNotification* notification) +{ + return notification->priv->webView; +} + +/** + * webkit_notification_get_id: + * @notification: a #WebKitNotification + * + * Obtains the unique id for the notification. + * + * Returns: the unique id for the notification + * + * Since: 2.8 + */ +guint64 webkit_notification_get_id(WebKitNotification* notification) +{ + g_return_val_if_fail(WEBKIT_IS_NOTIFICATION(notification), 0); + + return notification->priv->id; +} + +/** + * webkit_notification_get_title: + * @notification: a #WebKitNotification + * + * Obtains the title for the notification. + * + * Returns: the title for the notification + * + * Since: 2.8 + */ +const gchar* webkit_notification_get_title(WebKitNotification* notification) +{ + g_return_val_if_fail(WEBKIT_IS_NOTIFICATION(notification), nullptr); + + return notification->priv->title.data(); +} + +/** + * webkit_notification_get_body: + * @notification: a #WebKitNotification + * + * Obtains the body for the notification. + * + * Returns: the body for the notification + * + * Since: 2.8 + */ +const gchar* webkit_notification_get_body(WebKitNotification* notification) +{ + g_return_val_if_fail(WEBKIT_IS_NOTIFICATION(notification), nullptr); + + return notification->priv->body.data(); +} + +/** + * webkit_notification_get_tag: + * @notification: a #WebKitNotification + * + * Obtains the tag identifier for the notification. + * + * Returns: (allow-none): the tag for the notification + * + * Since: 2.16 + */ +const gchar* webkit_notification_get_tag(WebKitNotification* notification) +{ + g_return_val_if_fail(WEBKIT_IS_NOTIFICATION(notification), nullptr); + + const gchar* tag = notification->priv->tag.data(); + return notification->priv->tag.length() ? tag : nullptr; +} + +/** + * webkit_notification_close: + * @notification: a #WebKitNotification + * + * Closes the notification. + * + * Since: 2.8 + */ +void webkit_notification_close(WebKitNotification* notification) +{ + g_return_if_fail(WEBKIT_IS_NOTIFICATION(notification)); + + g_signal_emit(notification, signals[CLOSED], 0); +} + +/** + * webkit_notification_clicked: + * @notification: a #WebKitNotification + * + * Tells WebKit the notification has been clicked. This will emit the + * #WebKitNotification::clicked signal. + * + * Since: 2.12 + */ +void webkit_notification_clicked(WebKitNotification* notification) +{ + g_return_if_fail(WEBKIT_IS_NOTIFICATION(notification)); + + g_signal_emit(notification, signals[CLICKED], 0); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotification.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNotification.h new file mode 100644 index 000000000..1fd9ac646 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotification.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitNotification_h +#define WebKitNotification_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitForwardDeclarations.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_NOTIFICATION (webkit_notification_get_type()) +#define WEBKIT_NOTIFICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_NOTIFICATION, WebKitNotification)) +#define WEBKIT_IS_NOTIFICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_NOTIFICATION)) +#define WEBKIT_NOTIFICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_NOTIFICATION, WebKitNotificationClass)) +#define WEBKIT_IS_NOTIFICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_NOTIFICATION)) +#define WEBKIT_NOTIFICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_NOTIFICATION, WebKitNotificationClass)) + +typedef struct _WebKitNotification WebKitNotification; +typedef struct _WebKitNotificationClass WebKitNotificationClass; +typedef struct _WebKitNotificationPrivate WebKitNotificationPrivate; + +struct _WebKitNotification { + GObject parent; + + WebKitNotificationPrivate *priv; +}; + +struct _WebKitNotificationClass { + GObjectClass parent_class; + + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); + void (*_webkit_reserved4) (void); + void (*_webkit_reserved5) (void); +}; + +WEBKIT_API GType +webkit_notification_get_type (void); + +WEBKIT_API guint64 +webkit_notification_get_id (WebKitNotification *notification); + +WEBKIT_API const gchar * +webkit_notification_get_title (WebKitNotification *notification); + +WEBKIT_API const gchar * +webkit_notification_get_body (WebKitNotification *notification); + +WEBKIT_API const gchar * +webkit_notification_get_tag (WebKitNotification *notification); + +WEBKIT_API void +webkit_notification_close (WebKitNotification *notification); + +WEBKIT_API void +webkit_notification_clicked (WebKitNotification *notification); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequest.cpp new file mode 100644 index 000000000..2df447455 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequest.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitNotificationPermissionRequest.h" + +#include "NotificationPermissionRequest.h" +#include "WebKitNotificationPermissionRequestPrivate.h" +#include "WebKitPermissionRequest.h" + +using namespace WebKit; + +/** + * SECTION: WebKitNotificationPermissionRequest + * @Short_description: A permission request for displaying web notifications + * @Title: WebKitNotificationPermissionRequest + * @See_also: #WebKitPermissionRequest, #WebKitWebView + * + * WebKitNotificationPermissionRequest represents a request for + * permission to decide whether WebKit should provide the user with + * notifications through the Web Notification API. + * + * When a WebKitNotificationPermissionRequest is not handled by the user, + * it is denied by default. + * + * Since: 2.8 + */ + +static void webkit_permission_request_interface_init(WebKitPermissionRequestIface*); + +struct _WebKitNotificationPermissionRequestPrivate { + RefPtr<NotificationPermissionRequest> request; + bool madeDecision; +}; + +WEBKIT_DEFINE_TYPE_WITH_CODE( + WebKitNotificationPermissionRequest, webkit_notification_permission_request, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(WEBKIT_TYPE_PERMISSION_REQUEST, webkit_permission_request_interface_init)) + +static void webkitNotificationPermissionRequestAllow(WebKitPermissionRequest* request) +{ + ASSERT(WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST(request)); + + WebKitNotificationPermissionRequestPrivate* priv = WEBKIT_NOTIFICATION_PERMISSION_REQUEST(request)->priv; + + // Only one decision at a time. + if (priv->madeDecision) + return; + + priv->request->allow(); + priv->madeDecision = true; +} + +static void webkitNotificationPermissionRequestDeny(WebKitPermissionRequest* request) +{ + ASSERT(WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST(request)); + + WebKitNotificationPermissionRequestPrivate* priv = WEBKIT_NOTIFICATION_PERMISSION_REQUEST(request)->priv; + + // Only one decision at a time. + if (priv->madeDecision) + return; + + priv->request->deny(); + priv->madeDecision = true; +} + +static void webkit_permission_request_interface_init(WebKitPermissionRequestIface* iface) +{ + iface->allow = webkitNotificationPermissionRequestAllow; + iface->deny = webkitNotificationPermissionRequestDeny; +} + +static void webkitNotificationPermissionRequestDispose(GObject* object) +{ + // Default behaviour when no decision has been made is denying the request. + webkitNotificationPermissionRequestDeny(WEBKIT_PERMISSION_REQUEST(object)); + G_OBJECT_CLASS(webkit_notification_permission_request_parent_class)->dispose(object); +} + +static void webkit_notification_permission_request_class_init(WebKitNotificationPermissionRequestClass* klass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(klass); + objectClass->dispose = webkitNotificationPermissionRequestDispose; +} + +WebKitNotificationPermissionRequest* webkitNotificationPermissionRequestCreate(NotificationPermissionRequest* request) +{ + WebKitNotificationPermissionRequest* notificationPermissionRequest = WEBKIT_NOTIFICATION_PERMISSION_REQUEST(g_object_new(WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST, nullptr)); + notificationPermissionRequest->priv->request = request; + return notificationPermissionRequest; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequest.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequest.h new file mode 100644 index 000000000..d2fb41104 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequest.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitNotificationPermissionRequest_h +#define WebKitNotificationPermissionRequest_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST (webkit_notification_permission_request_get_type()) +#define WEBKIT_NOTIFICATION_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST, WebKitNotificationPermissionRequest)) +#define WEBKIT_NOTIFICATION_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST, WebKitNotificationPermissionRequestClass)) +#define WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST)) +#define WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST)) +#define WEBKIT_NOTIFICATION_PERMISSION_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST, WebKitNotificationPermissionRequestClass)) + +typedef struct _WebKitNotificationPermissionRequest WebKitNotificationPermissionRequest; +typedef struct _WebKitNotificationPermissionRequestClass WebKitNotificationPermissionRequestClass; +typedef struct _WebKitNotificationPermissionRequestPrivate WebKitNotificationPermissionRequestPrivate; + +struct _WebKitNotificationPermissionRequest { + GObject parent; + + /*< private >*/ + WebKitNotificationPermissionRequestPrivate *priv; +}; + +struct _WebKitNotificationPermissionRequestClass { + GObjectClass parent_class; +}; + +WEBKIT_API GType +webkit_notification_permission_request_get_type (void); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroupPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequestPrivate.h index 5fd865610..c23707e76 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroupPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequestPrivate.h @@ -17,13 +17,12 @@ * Boston, MA 02110-1301, USA. */ -#ifndef WebKitWebViewGroupPrivate_h -#define WebKitWebViewGroupPrivate_h +#ifndef WebKitNotificationPermissionRequestPrivate_h +#define WebKitNotificationPermissionRequestPrivate_h -#include "WebKitWebViewGroup.h" -#include "WebPageGroup.h" +#include "WebKitNotificationPermissionRequest.h" +#include "WebKitPrivate.h" -WebKitWebViewGroup* webkitWebViewGroupCreate(WebKit::WebPageGroup*); -WebKit::WebPageGroup* webkitWebViewGroupGetPageGroup(WebKitWebViewGroup*); +WebKitNotificationPermissionRequest* webkitNotificationPermissionRequestCreate(WebKit::NotificationPermissionRequest*); -#endif // WebKitWebViewGroupPrivate_h +#endif // WebKitNotificationPermissionRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPrivate.h new file mode 100644 index 000000000..49e9a6087 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPrivate.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2014 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitNotificationPrivate_h +#define WebKitNotificationPrivate_h + +#include "WebKitNotification.h" +#include "WebKitPrivate.h" +#include "WebNotification.h" +#include <wtf/text/CString.h> + +WebKitNotification* webkitNotificationCreate(WebKitWebView*, const WebKit::WebNotification&); +WebKitWebView* webkitNotificationGetWebView(WebKitNotification*); + +#endif // WebKitNotificationPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.cpp new file mode 100644 index 000000000..b60669adb --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * Copyright (C) 2014 Collabora Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 "WebKitNotificationProvider.h" + +#include "APIArray.h" +#include "APIDictionary.h" +#include "WKNotificationManager.h" +#include "WebKitNotificationPrivate.h" +#include "WebKitWebContextPrivate.h" +#include "WebKitWebViewPrivate.h" +#include "WebNotificationManagerProxy.h" +#include "WebPageProxy.h" +#include <wtf/text/CString.h> + +using namespace WebKit; + +static inline WebKitNotificationProvider* toNotificationProvider(const void* clientInfo) +{ + return static_cast<WebKitNotificationProvider*>(const_cast<void*>(clientInfo)); +} + +static void showCallback(WKPageRef page, WKNotificationRef notification, const void* clientInfo) +{ + toNotificationProvider(clientInfo)->show(toImpl(page), *toImpl(notification)); +} + +static void cancelCallback(WKNotificationRef notification, const void* clientInfo) +{ + toNotificationProvider(clientInfo)->cancel(*toImpl(notification)); +} + +static WKDictionaryRef notificationPermissionsCallback(const void* clientInfo) +{ + return toAPI(toNotificationProvider(clientInfo)->notificationPermissions().leakRef()); +} + +static void clearNotificationsCallback(WKArrayRef notificationIDs, const void* clientInfo) +{ + toNotificationProvider(clientInfo)->clearNotifications(toImpl(notificationIDs)); +} + +WebKitNotificationProvider::~WebKitNotificationProvider() +{ +} + +Ref<WebKitNotificationProvider> WebKitNotificationProvider::create(WebNotificationManagerProxy* notificationManager, WebKitWebContext* webContext) +{ + return adoptRef(*new WebKitNotificationProvider(notificationManager, webContext)); +} + +WebKitNotificationProvider::WebKitNotificationProvider(WebNotificationManagerProxy* notificationManager, WebKitWebContext* webContext) + : m_webContext(webContext) + , m_notificationManager(notificationManager) +{ + ASSERT(notificationManager); + + WKNotificationProviderV0 wkNotificationProvider = { + { + 0, // version + this, // clientInfo + }, + showCallback, + cancelCallback, + 0, // didDestroyNotificationCallback, + 0, // addNotificationManagerCallback, + 0, // removeNotificationManagerCallback, + notificationPermissionsCallback, + clearNotificationsCallback, + }; + + WKNotificationManagerSetProvider(toAPI(notificationManager), reinterpret_cast<WKNotificationProviderBase*>(&wkNotificationProvider)); +} + +void WebKitNotificationProvider::notificationCloseCallback(WebKitNotification* notification, WebKitNotificationProvider* provider) +{ + uint64_t notificationID = webkit_notification_get_id(notification); + Vector<RefPtr<API::Object>> arrayIDs; + arrayIDs.append(API::UInt64::create(notificationID)); + provider->m_notificationManager->providerDidCloseNotifications(API::Array::create(WTFMove(arrayIDs)).ptr()); + provider->m_notifications.remove(notificationID); +} + +void WebKitNotificationProvider::notificationClickedCallback(WebKitNotification* notification, WebKitNotificationProvider* provider) +{ + provider->m_notificationManager->providerDidClickNotification(webkit_notification_get_id(notification)); +} + +void WebKitNotificationProvider::withdrawAnyPreviousNotificationMatchingTag(const CString& tag) +{ + if (!tag.length()) + return; + + for (auto& notification : m_notifications.values()) { + if (tag == webkit_notification_get_tag(notification.get())) { + webkit_notification_close(notification.get()); + break; + } + } + +#ifndef NDEBUG + for (auto& notification : m_notifications.values()) + ASSERT(tag != webkit_notification_get_tag(notification.get())); +#endif +} + +void WebKitNotificationProvider::show(WebPageProxy* page, const WebNotification& webNotification) +{ + GRefPtr<WebKitNotification> notification = m_notifications.get(webNotification.notificationID()); + + if (!notification) { + withdrawAnyPreviousNotificationMatchingTag(webNotification.tag().utf8()); + notification = adoptGRef(webkitNotificationCreate(WEBKIT_WEB_VIEW(page->viewWidget()), webNotification)); + g_signal_connect(notification.get(), "closed", G_CALLBACK(notificationCloseCallback), this); + g_signal_connect(notification.get(), "clicked", G_CALLBACK(notificationClickedCallback), this); + m_notifications.set(webNotification.notificationID(), notification); + } + + if (webkitWebViewEmitShowNotification(WEBKIT_WEB_VIEW(page->viewWidget()), notification.get())) + m_notificationManager->providerDidShowNotification(webNotification.notificationID()); +} + +void WebKitNotificationProvider::cancelNotificationByID(uint64_t notificationID) +{ + if (GRefPtr<WebKitNotification> notification = m_notifications.get(notificationID)) + webkit_notification_close(notification.get()); +} + +void WebKitNotificationProvider::cancel(const WebNotification& webNotification) +{ + cancelNotificationByID(webNotification.notificationID()); +} + +void WebKitNotificationProvider::clearNotifications(const API::Array* notificationIDs) +{ + for (const auto& item : notificationIDs->elementsOfType<API::UInt64>()) + cancelNotificationByID(item->value()); +} + +RefPtr<API::Dictionary> WebKitNotificationProvider::notificationPermissions() +{ + webkitWebContextInitializeNotificationPermissions(m_webContext); + return m_notificationPermissions; +} + +void WebKitNotificationProvider::setNotificationPermissions(HashMap<String, RefPtr<API::Object>>&& permissionsMap) +{ + m_notificationPermissions = API::Dictionary::create(WTFMove(permissionsMap)); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.h new file mode 100644 index 000000000..49c9b9aaf --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitNotificationProvider_h +#define WebKitNotificationProvider_h + +#include "WebKitPrivate.h" +#include "WebKitNotification.h" +#include "WebKitWebContext.h" +#include <wtf/HashMap.h> +#include <wtf/Ref.h> +#include <wtf/RefCounted.h> + +namespace API { +class Array; +} + +namespace WebKit { + +class WebKitNotificationProvider : public RefCounted<WebKitNotificationProvider> { +public: + virtual ~WebKitNotificationProvider(); + static Ref<WebKitNotificationProvider> create(WebNotificationManagerProxy*, WebKitWebContext*); + + void show(WebPageProxy*, const WebNotification&); + void cancel(const WebNotification&); + void clearNotifications(const API::Array*); + + RefPtr<API::Dictionary> notificationPermissions(); + void setNotificationPermissions(HashMap<String, RefPtr<API::Object>>&&); + +private: + WebKitNotificationProvider(WebNotificationManagerProxy*, WebKitWebContext*); + + void cancelNotificationByID(uint64_t); + static void notificationCloseCallback(WebKitNotification*, WebKitNotificationProvider*); + static void notificationClickedCallback(WebKitNotification*, WebKitNotificationProvider*); + + void withdrawAnyPreviousNotificationMatchingTag(const CString&); + + WebKitWebContext* m_webContext; + RefPtr<API::Dictionary> m_notificationPermissions; + RefPtr<WebNotificationManagerProxy> m_notificationManager; + HashMap<uint64_t, GRefPtr<WebKitNotification>> m_notifications; +}; + +} // namespace WebKit + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPlugin.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPlugin.cpp index 2bcb89c50..b6dec1d3a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPlugin.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPlugin.cpp @@ -55,7 +55,7 @@ struct _WebKitPluginPrivate { WEBKIT_DEFINE_TYPE(WebKitPlugin, webkit_plugin, G_TYPE_OBJECT) -static void webkit_plugin_class_init(WebKitPluginClass* pluginClass) +static void webkit_plugin_class_init(WebKitPluginClass*) { } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.cpp index 1eb6b1ec6..243f40990 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.cpp @@ -20,65 +20,48 @@ #include "config.h" #include "WebKitPolicyClient.h" +#include "APIPolicyClient.h" #include "WebKitNavigationPolicyDecisionPrivate.h" #include "WebKitResponsePolicyDecisionPrivate.h" #include "WebKitWebViewBasePrivate.h" #include "WebKitWebViewPrivate.h" -#include <wtf/gobject/GRefPtr.h> +#include "WebsitePolicies.h" +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; -static void decidePolicyForNavigationAction(WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKFrameRef originatingFrame, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) -{ - GRefPtr<WebKitNavigationPolicyDecision> decision = - adoptGRef(webkitNavigationPolicyDecisionCreate(static_cast<WebKitNavigationType>(navigationType), - wkEventMouseButtonToWebKitMouseButton(mouseButton), - wkEventModifiersToGdkModifiers(modifiers), - toImpl(request), - 0, /* frame name */ - toImpl(listener))); - webkitWebViewMakePolicyDecision(WEBKIT_WEB_VIEW(clientInfo), - WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION, - WEBKIT_POLICY_DECISION(decision.get())); -} +class PolicyClient: public API::PolicyClient { +public: + explicit PolicyClient(WebKitWebView* webView) + : m_webView(webView) + { + } -static void decidePolicyForNewWindowAction(WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKStringRef frameName, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) -{ - GRefPtr<WebKitNavigationPolicyDecision> decision = - adoptGRef(webkitNavigationPolicyDecisionCreate(static_cast<WebKitNavigationType>(navigationType), - wkEventMouseButtonToWebKitMouseButton(mouseButton), - wkEventModifiersToGdkModifiers(modifiers), - toImpl(request), - toImpl(frameName)->string().utf8().data(), - toImpl(listener))); - webkitWebViewMakePolicyDecision(WEBKIT_WEB_VIEW(clientInfo), - WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION, - WEBKIT_POLICY_DECISION(decision.get())); -} +private: + void decidePolicyForNavigationAction(WebPageProxy&, WebFrameProxy*, const NavigationActionData& navigationActionData, WebFrameProxy* /*originatingFrame*/, const WebCore::ResourceRequest& /*originalRequest*/, const WebCore::ResourceRequest& request, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* /*userData*/) override + { + GRefPtr<WebKitPolicyDecision> decision = adoptGRef(webkitNavigationPolicyDecisionCreate(navigationActionData, request, listener.ptr())); + webkitWebViewMakePolicyDecision(m_webView, WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION, decision.get()); + } -static void decidePolicyForResponse(WKPageRef page, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef request, bool canShowMIMEType, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) -{ - GRefPtr<WebKitResponsePolicyDecision> decision = - adoptGRef(webkitResponsePolicyDecisionCreate(toImpl(request), toImpl(response), canShowMIMEType, toImpl(listener))); - webkitWebViewMakePolicyDecision(WEBKIT_WEB_VIEW(clientInfo), - WEBKIT_POLICY_DECISION_TYPE_RESPONSE, - WEBKIT_POLICY_DECISION(decision.get())); -} + void decidePolicyForNewWindowAction(WebPageProxy&, WebFrameProxy&, const NavigationActionData& navigationActionData, const WebCore::ResourceRequest& request, const String& frameName, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* /*userData*/) override + { + GRefPtr<WebKitPolicyDecision> decision = adoptGRef(webkitNewWindowPolicyDecisionCreate(navigationActionData, request, frameName, listener.ptr())); + webkitWebViewMakePolicyDecision(m_webView, WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION, decision.get()); + } + + void decidePolicyForResponse(WebPageProxy&, WebFrameProxy&, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& request, bool canShowMIMEType, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* /*userData*/) override + { + GRefPtr<WebKitPolicyDecision> decision = adoptGRef(webkitResponsePolicyDecisionCreate(request, response, canShowMIMEType, listener.ptr())); + webkitWebViewMakePolicyDecision(m_webView, WEBKIT_POLICY_DECISION_TYPE_RESPONSE, decision.get()); + } + + WebKitWebView* m_webView; +}; void attachPolicyClientToView(WebKitWebView* webView) { - WKPagePolicyClientV1 policyClient = { - { - 1, // version - webView, // clientInfo - }, - 0, // decidePolicyForNavigationAction_deprecatedForUseWithV0 - decidePolicyForNewWindowAction, - 0, // decidePolicyForResponse_deprecatedForUseWithV0 - 0, // unableToImplementPolicy - decidePolicyForNavigationAction, - decidePolicyForResponse - }; - WKPageSetPagePolicyClient(toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))), &policyClient.base); + WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)); + page->setPolicyClient(std::make_unique<PolicyClient>(webView)); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.cpp index ee44eaebb..688728901 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.cpp @@ -22,6 +22,7 @@ #include "WebFramePolicyListenerProxy.h" #include "WebKitPolicyDecisionPrivate.h" +#include "WebsitePolicies.h" using namespace WebKit; @@ -79,7 +80,7 @@ void webkit_policy_decision_use(WebKitPolicyDecision* decision) if (decision->priv->madePolicyDecision) return; - decision->priv->listener->use(); + decision->priv->listener->use({ }); decision->priv->madePolicyDecision = true; } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.cpp new file mode 100644 index 000000000..21037e7a2 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2017 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitPrintCustomWidget.h" + +#include "WebKitPrintCustomWidgetPrivate.h" +#include <glib/gi18n-lib.h> +#include <gtk/gtk.h> +#include <wtf/glib/GRefPtr.h> + +using namespace WebKit; + +/** + * SECTION: WebKitPrintCustomWidget + * @Short_description: Allows to embed a custom widget in print dialog + * @Title: WebKitPrintCustomWidget + * @See_also: #WebKitPrintOperation + * + * A WebKitPrintCustomWidget allows to embed a custom widget in the print + * dialog by connecting to the #WebKitPrintOperation::create-custom-widget + * signal, creating a new WebKitPrintCustomWidget with + * webkit_print_custom_widget_new() and returning it from there. You can later + * use webkit_print_operation_run_dialog() to display the dialog. + * + * Since: 2.16 + */ + +enum { + APPLY, + UPDATE, + + LAST_SIGNAL +}; + +enum { + PROP_0, + + PROP_WIDGET, + PROP_TITLE +}; + +struct _WebKitPrintCustomWidgetPrivate { + CString title; + GRefPtr<GtkWidget> widget; +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +WEBKIT_DEFINE_TYPE(WebKitPrintCustomWidget, webkit_print_custom_widget, G_TYPE_OBJECT) + +static void webkitPrintCustomWidgetGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) +{ + WebKitPrintCustomWidget* printCustomWidget = WEBKIT_PRINT_CUSTOM_WIDGET(object); + + switch (propId) { + case PROP_WIDGET: + g_value_set_object(value, webkit_print_custom_widget_get_widget(printCustomWidget)); + break; + case PROP_TITLE: + g_value_set_string(value, webkit_print_custom_widget_get_title(printCustomWidget)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkitPrintCustomWidgetSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) +{ + WebKitPrintCustomWidget* printCustomWidget = WEBKIT_PRINT_CUSTOM_WIDGET(object); + + switch (propId) { + case PROP_WIDGET: + printCustomWidget->priv->widget = GTK_WIDGET(g_value_get_object(value)); + break; + case PROP_TITLE: + printCustomWidget->priv->title = g_value_get_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkit_print_custom_widget_class_init(WebKitPrintCustomWidgetClass* printCustomWidgetClass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(printCustomWidgetClass); + objectClass->get_property = webkitPrintCustomWidgetGetProperty; + objectClass->set_property = webkitPrintCustomWidgetSetProperty; + + /** + * WebKitPrintCustomWidget:widget: + * + * The custom #GtkWidget that will be embedded in the dialog. + * + * Since: 2.16 + */ + g_object_class_install_property( + objectClass, + PROP_WIDGET, + g_param_spec_object( + "widget", + _("Widget"), + _("Widget that will be added to the print dialog."), + GTK_TYPE_WIDGET, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitPrintCustomWidget:title: + * + * The title of the custom widget. + * + * Since: 2.16 + */ + g_object_class_install_property( + objectClass, + PROP_TITLE, + g_param_spec_string( + "title", + _("Title"), + _("Title of the widget that will be added to the print dialog."), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitPrintCustomWidget::update: + * @print_custom_widget: the #WebKitPrintCustomWidget on which the signal was emitted + * @page_setup: actual page setup + * @print_settings: actual print settings + * + * Emitted after change of selected printer in the dialog. The actual page setup + * and print settings are available and the custom widget can actualize itself + * according to their values. + * + * Since: 2.16 + */ + signals[UPDATE] = + g_signal_new( + "update", + G_TYPE_FROM_CLASS(printCustomWidgetClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitPrintCustomWidgetClass, update), + 0, 0, + g_cclosure_marshal_generic, + G_TYPE_NONE, 2, + GTK_TYPE_PAGE_SETUP, GTK_TYPE_PRINT_SETTINGS); + + /** + * WebKitPrintCustomWidget::apply: + * @print_custom_widget: the #WebKitPrintCustomWidget on which the signal was emitted + * + * Emitted right before the printing will start. You should read the information + * from the widget and update the content based on it if necessary. The widget + * is not guaranteed to be valid at a later time. + * + * Since: 2.16 + */ + signals[APPLY] = + g_signal_new( + "apply", + G_TYPE_FROM_CLASS(printCustomWidgetClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitPrintCustomWidgetClass, apply), + 0, 0, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +/** + * webkit_print_custom_widget_new: + * @widget: a #GtkWidget + * @title: a @widget's title + * + * Create a new #WebKitPrintCustomWidget with given @widget and @title. The @widget + * ownership is taken and it is destroyed together with the dialog even if this + * object could still be alive at that point. You typically want to pass a container + * widget with multiple widgets in it. + * + * Returns: (transfer full): a new #WebKitPrintOperation. + * + * Since: 2.16 + */ +WebKitPrintCustomWidget* webkit_print_custom_widget_new(GtkWidget* widget, const char* title) +{ + g_return_val_if_fail(GTK_IS_WIDGET(widget), nullptr); + g_return_val_if_fail(title, nullptr); + + return WEBKIT_PRINT_CUSTOM_WIDGET(g_object_new(WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, "widget", widget, "title", title, nullptr)); +} + +/** + * webkit_print_custom_widget_get_widget: + * @print_custom_widget: a #WebKitPrintCustomWidget + * + * Return the value of #WebKitPrintCustomWidget:widget property for the given + * @print_custom_widget object. The returned value will always be valid if called + * from #WebKitPrintCustomWidget::apply or #WebKitPrintCustomWidget::update + * callbacks, but it will be %NULL if called after the + * #WebKitPrintCustomWidget::apply signal is emitted. + * + * Returns: (transfer none): a #GtkWidget. + * + * Since: 2.16 + */ +GtkWidget* webkit_print_custom_widget_get_widget(WebKitPrintCustomWidget* printCustomWidget) +{ + g_return_val_if_fail(WEBKIT_IS_PRINT_CUSTOM_WIDGET(printCustomWidget), nullptr); + + return printCustomWidget->priv->widget.get(); +} + +/** + * webkit_print_custom_widget_get_title: + * @print_custom_widget: a #WebKitPrintCustomWidget + * + * Return the value of #WebKitPrintCustomWidget:title property for the given + * @print_custom_widget object. + * + * Returns: Title of the @print_custom_widget. + * + * Since: 2.16 + */ +const gchar* webkit_print_custom_widget_get_title(WebKitPrintCustomWidget* printCustomWidget) +{ + g_return_val_if_fail(WEBKIT_IS_PRINT_CUSTOM_WIDGET(printCustomWidget), nullptr); + + return printCustomWidget->priv->title.data(); +} + +void webkitPrintCustomWidgetEmitCustomWidgetApplySignal(WebKitPrintCustomWidget* printCustomWidget) +{ + g_signal_emit(printCustomWidget, signals[APPLY], 0); + printCustomWidget->priv->widget = nullptr; +} + +void webkitPrintCustomWidgetEmitUpdateCustomWidgetSignal(WebKitPrintCustomWidget *printCustomWidget, GtkPageSetup *pageSetup, GtkPrintSettings *printSettings) +{ + g_signal_emit(printCustomWidget, signals[UPDATE], 0, pageSetup, printSettings); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.h new file mode 100644 index 000000000..e6cc84a0c --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2017 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitPrintCustomWidget_h +#define WebKitPrintCustomWidget_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_PRINT_CUSTOM_WIDGET (webkit_print_custom_widget_get_type()) +#define WEBKIT_PRINT_CUSTOM_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, WebKitPrintCustomWidget)) +#define WEBKIT_IS_PRINT_CUSTOM_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_PRINT_CUSTOM_WIDGET)) +#define WEBKIT_PRINT_CUSTOM_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, WebKitPrintCustomWidgetClass)) +#define WEBKIT_IS_PRINT_CUSTOM_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_PRINT_CUSTOM_WIDGET)) +#define WEBKIT_PRINT_CUSTOM_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, WebKitPrintCustomWidgetClass)) + +typedef struct _WebKitPrintCustomWidget WebKitPrintCustomWidget; +typedef struct _WebKitPrintCustomWidgetClass WebKitPrintCustomWidgetClass; +typedef struct _WebKitPrintCustomWidgetPrivate WebKitPrintCustomWidgetPrivate; + +struct _WebKitPrintCustomWidget { + GObject parent; + + WebKitPrintCustomWidgetPrivate *priv; +}; + +struct _WebKitPrintCustomWidgetClass { + GObjectClass parent_class; + + void (* apply) (WebKitPrintCustomWidget *print_custom_widget, + GtkWidget *widget); + void (* update) (WebKitPrintCustomWidget *print_custom_widget, + GtkWidget *widget, + GtkPageSetup *page_setup, + GtkPrintSettings *print_settings); + + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); +}; + +WEBKIT_API GType +webkit_print_custom_widget_get_type (void); + +WEBKIT_API WebKitPrintCustomWidget * +webkit_print_custom_widget_new (GtkWidget *widget, + const char *title); + +WEBKIT_API GtkWidget * +webkit_print_custom_widget_get_widget (WebKitPrintCustomWidget *print_custom_widget); + +WEBKIT_API const gchar * +webkit_print_custom_widget_get_title (WebKitPrintCustomWidget *print_custom_widget); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidgetPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidgetPrivate.h new file mode 100644 index 000000000..d251d5055 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidgetPrivate.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "WebKitPrintCustomWidget.h" +#include "WebKitPrivate.h" +#include <gtk/gtk.h> + +void webkitPrintCustomWidgetEmitCustomWidgetApplySignal(WebKitPrintCustomWidget*); +void webkitPrintCustomWidgetEmitUpdateCustomWidgetSignal(WebKitPrintCustomWidget*, GtkPageSetup*, GtkPrintSettings*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp index 75b435baf..dab8c9d89 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp @@ -20,6 +20,7 @@ #include "config.h" #include "WebKitPrintOperation.h" +#include "WebKitPrintCustomWidgetPrivate.h" #include "WebKitPrintOperationPrivate.h" #include "WebKitPrivate.h" #include "WebKitWebViewBasePrivate.h" @@ -27,11 +28,11 @@ #include <WebCore/GtkUtilities.h> #include <WebCore/NotImplemented.h> #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> -#ifdef HAVE_GTK_UNIX_PRINTING +#if HAVE(GTK_UNIX_PRINTING) #include <gtk/gtkunixprint.h> #endif @@ -60,6 +61,7 @@ enum { enum { FINISHED, FAILED, + CREATE_CUSTOM_WIDGET, LAST_SIGNAL }; @@ -128,6 +130,15 @@ static void webkitPrintOperationSetProperty(GObject* object, guint propId, const } } +static gboolean webkitPrintOperationAccumulatorObjectHandled(GSignalInvocationHint*, GValue* returnValue, const GValue* handlerReturn, gpointer) +{ + void* object = g_value_get_object(handlerReturn); + if (object) + g_value_set_object(returnValue, object); + + return !object; +} + static void webkit_print_operation_class_init(WebKitPrintOperationClass* printOperationClass) { GObjectClass* gObjectClass = G_OBJECT_CLASS(printOperationClass); @@ -198,16 +209,45 @@ static void webkit_print_operation_class_init(WebKitPrintOperationClass* printOp * The #WebKitPrintOperation::finished signal is emitted after this one. */ signals[FAILED] = - g_signal_new("failed", - G_TYPE_FROM_CLASS(gObjectClass), - G_SIGNAL_RUN_LAST, - 0, 0, 0, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); + g_signal_new( + "failed", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + 0, 0, 0, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + G_TYPE_ERROR | G_SIGNAL_TYPE_STATIC_SCOPE); + + /** + * WebKitPrintOperation::create-custom-widget: + * @print_operation: the #WebKitPrintOperation on which the signal was emitted + * + * Emitted when displaying the print dialog with webkit_print_operation_run_dialog(). + * The returned #WebKitPrintCustomWidget will be added to the print dialog and + * it will be owned by the @print_operation. However, the object is guaranteed + * to be alive until the #WebKitPrintCustomWidget::apply is emitted. + * + * Returns: (transfer full): A #WebKitPrintCustomWidget that will be embedded in the dialog. + * + * Since: 2.16 + */ + signals[CREATE_CUSTOM_WIDGET] = + g_signal_new( + "create-custom-widget", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + 0, + webkitPrintOperationAccumulatorObjectHandled, 0, + g_cclosure_marshal_generic, + WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, 0); +} + +#if HAVE(GTK_UNIX_PRINTING) +static void notifySelectedPrinterCallback(GtkPrintUnixDialog* dialog, GParamSpec*, WebKitPrintCustomWidget* printCustomWidget) +{ + webkitPrintCustomWidgetEmitUpdateCustomWidgetSignal(printCustomWidget, gtk_print_unix_dialog_get_page_setup(dialog), gtk_print_unix_dialog_get_settings(dialog)); } -#ifdef HAVE_GTK_UNIX_PRINTING static WebKitPrintOperationResponse webkitPrintOperationRunDialog(WebKitPrintOperation* printOperation, GtkWindow* parent) { GtkPrintUnixDialog* printDialog = GTK_PRINT_UNIX_DIALOG(gtk_print_unix_dialog_new(0, parent)); @@ -232,11 +272,23 @@ static WebKitPrintOperationResponse webkitPrintOperationRunDialog(WebKitPrintOpe gtk_print_unix_dialog_set_embed_page_setup(printDialog, TRUE); + GRefPtr<WebKitPrintCustomWidget> customWidget; + g_signal_emit(printOperation, signals[CREATE_CUSTOM_WIDGET], 0, &customWidget.outPtr()); + if (customWidget) { + const gchar* widgetTitle = webkit_print_custom_widget_get_title(customWidget.get()); + GtkWidget* widget = webkit_print_custom_widget_get_widget(customWidget.get()); + + g_signal_connect(printDialog, "notify::selected-printer", G_CALLBACK(notifySelectedPrinterCallback), customWidget.get()); + gtk_print_unix_dialog_add_custom_tab(printDialog, widget, gtk_label_new(widgetTitle)); + } + WebKitPrintOperationResponse returnValue = WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL; if (gtk_dialog_run(GTK_DIALOG(printDialog)) == GTK_RESPONSE_OK) { priv->printSettings = adoptGRef(gtk_print_unix_dialog_get_settings(printDialog)); priv->pageSetup = gtk_print_unix_dialog_get_page_setup(printDialog); returnValue = WEBKIT_PRINT_OPERATION_RESPONSE_PRINT; + if (customWidget) + webkitPrintCustomWidgetEmitCustomWidgetApplySignal(customWidget.get()); } gtk_widget_destroy(GTK_WIDGET(printDialog)); @@ -252,30 +304,31 @@ static WebKitPrintOperationResponse webkitPrintOperationRunDialog(WebKitPrintOpe } #endif -static void drawPagesForPrintingCompleted(WKErrorRef wkPrintError, WKErrorRef, void* context) +static void drawPagesForPrintingCompleted(API::Error* wkPrintError, WebKitPrintOperation* printOperation) { - GRefPtr<WebKitPrintOperation> printOperation = adoptGRef(WEBKIT_PRINT_OPERATION(context)); - // When running synchronously WebPageProxy::printFrame() calls endPrinting(). if (printOperation->priv->printMode == PrintInfo::PrintModeAsync && printOperation->priv->webView) { WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView)); page->endPrinting(); } - const WebCore::ResourceError& resourceError = wkPrintError ? toImpl(wkPrintError)->platformError() : WebCore::ResourceError(); + const WebCore::ResourceError& resourceError = wkPrintError ? wkPrintError->platformError() : WebCore::ResourceError(); if (!resourceError.isNull()) { GUniquePtr<GError> printError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()), - resourceError.errorCode(), resourceError.localizedDescription().utf8().data())); - g_signal_emit(printOperation.get(), signals[FAILED], 0, printError.get()); + toWebKitError(resourceError.errorCode()), resourceError.localizedDescription().utf8().data())); + g_signal_emit(printOperation, signals[FAILED], 0, printError.get()); } - g_signal_emit(printOperation.get(), signals[FINISHED], 0, NULL); + g_signal_emit(printOperation, signals[FINISHED], 0, NULL); } static void webkitPrintOperationPrintPagesForFrame(WebKitPrintOperation* printOperation, WebFrameProxy* webFrame, GtkPrintSettings* printSettings, GtkPageSetup* pageSetup) { PrintInfo printInfo(printSettings, pageSetup, printOperation->priv->printMode); WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView)); - page->drawPagesForPrinting(webFrame, printInfo, PrintFinishedCallback::create(g_object_ref(printOperation), &drawPagesForPrintingCompleted)); + g_object_ref(printOperation); + page->drawPagesForPrinting(webFrame, printInfo, PrintFinishedCallback::create([printOperation](API::Error* printError, CallbackBase::Error) { + drawPagesForPrintingCompleted(printError, adoptGRef(printOperation).get()); + })); } WebKitPrintOperationResponse webkitPrintOperationRunDialogForFrame(WebKitPrintOperation* printOperation, GtkWindow* parent, WebFrameProxy* webFrame) diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.cpp index d34b9c471..2c971c22d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.cpp @@ -20,6 +20,9 @@ #include "config.h" #include "WebKitPrivate.h" +#include "ErrorsGtk.h" +#include "WebEvent.h" +#include "WebKitError.h" #include <gdk/gdk.h> unsigned wkEventModifiersToGdkModifiers(WKEventModifiers wkModifiers) @@ -33,9 +36,64 @@ unsigned wkEventModifiersToGdkModifiers(WKEventModifiers wkModifiers) modifiers |= GDK_MOD1_MASK; if (wkModifiers & kWKEventModifiersMetaKey) modifiers |= GDK_META_MASK; + if (wkModifiers & kWKEventModifiersCapsLockKey) + modifiers |= GDK_LOCK_MASK; return modifiers; } +unsigned toGdkModifiers(WebKit::WebEvent::Modifiers wkModifiers) +{ + unsigned modifiers = 0; + if (wkModifiers & WebKit::WebEvent::Modifiers::ShiftKey) + modifiers |= GDK_SHIFT_MASK; + if (wkModifiers & WebKit::WebEvent::Modifiers::ControlKey) + modifiers |= GDK_CONTROL_MASK; + if (wkModifiers & WebKit::WebEvent::Modifiers::AltKey) + modifiers |= GDK_MOD1_MASK; + if (wkModifiers & WebKit::WebEvent::Modifiers::MetaKey) + modifiers |= GDK_META_MASK; + if (wkModifiers & WebKit::WebEvent::Modifiers::CapsLockKey) + modifiers |= GDK_LOCK_MASK; + return modifiers; +} + +WebKitNavigationType toWebKitNavigationType(WebCore::NavigationType type) +{ + switch (type) { + case WebCore::NavigationType::LinkClicked: + return WEBKIT_NAVIGATION_TYPE_LINK_CLICKED; + case WebCore::NavigationType::FormSubmitted: + return WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED; + case WebCore::NavigationType::BackForward: + return WEBKIT_NAVIGATION_TYPE_BACK_FORWARD; + case WebCore::NavigationType::Reload: + return WEBKIT_NAVIGATION_TYPE_RELOAD; + case WebCore::NavigationType::FormResubmitted: + return WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED; + case WebCore::NavigationType::Other: + return WEBKIT_NAVIGATION_TYPE_OTHER; + default: + ASSERT_NOT_REACHED(); + return WEBKIT_NAVIGATION_TYPE_OTHER; + } +} + +unsigned toWebKitMouseButton(WebKit::WebMouseEvent::Button button) +{ + switch (button) { + case WebKit::WebMouseEvent::Button::NoButton: + return 0; + case WebKit::WebMouseEvent::Button::LeftButton: + return 1; + case WebKit::WebMouseEvent::Button::MiddleButton: + return 2; + case WebKit::WebMouseEvent::Button::RightButton: + return 3; + } + ASSERT_NOT_REACHED(); + return 0; +} + unsigned wkEventMouseButtonToWebKitMouseButton(WKEventMouseButton wkButton) { switch (wkButton) { @@ -51,3 +109,109 @@ unsigned wkEventMouseButtonToWebKitMouseButton(WKEventMouseButton wkButton) ASSERT_NOT_REACHED(); return 0; } + +unsigned toWebKitError(unsigned webCoreError) +{ + switch (webCoreError) { + case WebCore::NetworkErrorFailed: + return WEBKIT_NETWORK_ERROR_FAILED; + case WebCore::NetworkErrorTransport: + return WEBKIT_NETWORK_ERROR_TRANSPORT; + case WebCore::NetworkErrorUnknownProtocol: + return WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL; + case WebCore::NetworkErrorCancelled: + return WEBKIT_NETWORK_ERROR_CANCELLED; + case WebCore::NetworkErrorFileDoesNotExist: + return WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST; + case WebCore::PolicyErrorFailed: + return WEBKIT_POLICY_ERROR_FAILED; + case WebCore::PolicyErrorCannotShowMimeType: + return WEBKIT_POLICY_ERROR_CANNOT_SHOW_MIME_TYPE; + case WebCore::PolicyErrorCannotShowURL: + return WEBKIT_POLICY_ERROR_CANNOT_SHOW_URI; + case WebCore::PolicyErrorFrameLoadInterruptedByPolicyChange: + return WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE; + case WebCore::PolicyErrorCannotUseRestrictedPort: + return WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT; + case WebCore::PluginErrorFailed: + return WEBKIT_PLUGIN_ERROR_FAILED; + case WebCore::PluginErrorCannotFindPlugin: + return WEBKIT_PLUGIN_ERROR_CANNOT_FIND_PLUGIN; + case WebCore::PluginErrorCannotLoadPlugin: + return WEBKIT_PLUGIN_ERROR_CANNOT_LOAD_PLUGIN; + case WebCore::PluginErrorJavaUnavailable: + return WEBKIT_PLUGIN_ERROR_JAVA_UNAVAILABLE; + case WebCore::PluginErrorConnectionCancelled: + return WEBKIT_PLUGIN_ERROR_CONNECTION_CANCELLED; + case WebCore::PluginErrorWillHandleLoad: + return WEBKIT_PLUGIN_ERROR_WILL_HANDLE_LOAD; + case WebCore::DownloadErrorNetwork: + return WEBKIT_DOWNLOAD_ERROR_NETWORK; + case WebCore::DownloadErrorCancelledByUser: + return WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER; + case WebCore::DownloadErrorDestination: + return WEBKIT_DOWNLOAD_ERROR_DESTINATION; + case WebCore::PrintErrorGeneral: + return WEBKIT_PRINT_ERROR_GENERAL; + case WebCore::PrintErrorPrinterNotFound: + return WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND; + case WebCore::PrintErrorInvalidPageRange: + return WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE; + default: + // This may be a user app defined error, which needs to be passed as-is. + return webCoreError; + } +} + +unsigned toWebCoreError(unsigned webKitError) +{ + switch (webKitError) { + case WEBKIT_NETWORK_ERROR_FAILED: + return WebCore::NetworkErrorFailed; + case WEBKIT_NETWORK_ERROR_TRANSPORT: + return WebCore::NetworkErrorTransport; + case WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL: + return WebCore::NetworkErrorUnknownProtocol; + case WEBKIT_NETWORK_ERROR_CANCELLED: + return WebCore::NetworkErrorCancelled; + case WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST: + return WebCore::NetworkErrorFileDoesNotExist; + case WEBKIT_POLICY_ERROR_FAILED: + return WebCore::PolicyErrorFailed; + case WEBKIT_POLICY_ERROR_CANNOT_SHOW_MIME_TYPE: + return WebCore::PolicyErrorCannotShowMimeType; + case WEBKIT_POLICY_ERROR_CANNOT_SHOW_URI: + return WebCore::PolicyErrorCannotShowURL; + case WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE: + return WebCore::PolicyErrorFrameLoadInterruptedByPolicyChange; + case WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT: + return WebCore::PolicyErrorCannotUseRestrictedPort; + case WEBKIT_PLUGIN_ERROR_FAILED: + return WebCore::PluginErrorFailed; + case WEBKIT_PLUGIN_ERROR_CANNOT_FIND_PLUGIN: + return WebCore::PluginErrorCannotFindPlugin; + case WEBKIT_PLUGIN_ERROR_CANNOT_LOAD_PLUGIN: + return WebCore::PluginErrorCannotLoadPlugin; + case WEBKIT_PLUGIN_ERROR_JAVA_UNAVAILABLE: + return WebCore::PluginErrorJavaUnavailable; + case WEBKIT_PLUGIN_ERROR_CONNECTION_CANCELLED: + return WebCore::PluginErrorConnectionCancelled; + case WEBKIT_PLUGIN_ERROR_WILL_HANDLE_LOAD: + return WebCore::PluginErrorWillHandleLoad; + case WEBKIT_DOWNLOAD_ERROR_NETWORK: + return WebCore::DownloadErrorNetwork; + case WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER: + return WebCore::DownloadErrorCancelledByUser; + case WEBKIT_DOWNLOAD_ERROR_DESTINATION: + return WebCore::DownloadErrorDestination; + case WEBKIT_PRINT_ERROR_GENERAL: + return WebCore::PrintErrorGeneral; + case WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND: + return WebCore::PrintErrorPrinterNotFound; + case WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE: + return WebCore::PrintErrorInvalidPageRange; + default: + // This may be a user app defined error, which needs to be passed as-is. + return webKitError; + } +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h index bd060ed32..d072a5ef2 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h @@ -26,22 +26,22 @@ #ifndef WebKitPrivate_h #define WebKitPrivate_h -#include <WebKit2/WKAPICast.h> -#include <WebKit2/WKDownload.h> -#include <WebKit2/WKFindOptions.h> -#include <WebKit2/WKFullScreenClientGtk.h> -#include <WebKit2/WKGeolocationManager.h> -#include <WebKit2/WKGeolocationPermissionRequest.h> -#include <WebKit2/WKGeolocationPosition.h> -#include <WebKit2/WKIconDatabase.h> -#include <WebKit2/WKInspector.h> -#include <WebKit2/WKInspectorClientGtk.h> -#include <WebKit2/WKRetainPtr.h> -#include <WebKit2/WKSerializedScriptValue.h> -#include <WebKit2/WKSoupCustomProtocolRequestManager.h> -#include <WebKit2/WKString.h> -#include <WebKit2/WKTextChecker.h> -#include <WebKit2/WebKit2_C.h> +#include "WebKitNavigationAction.h" +#include <WebKit/WKAPICast.h> +#include <WebKit/WKDownload.h> +#include <WebKit/WKFindOptions.h> +#include <WebKit/WKFullScreenClientGtk.h> +#include <WebKit/WKGeolocationManager.h> +#include <WebKit/WKGeolocationPermissionRequest.h> +#include <WebKit/WKGeolocationPosition.h> +#include <WebKit/WKIconDatabase.h> +#include <WebKit/WKInspector.h> +#include <WebKit/WKInspectorClientGtk.h> +#include <WebKit/WKRetainPtr.h> +#include <WebKit/WKSerializedScriptValue.h> +#include <WebKit/WKString.h> +#include <WebKit/WKUserMediaPermissionRequest.h> +#include <WebKit/WebKit2_C.h> #include <glib.h> #include <wtf/Assertions.h> @@ -49,20 +49,17 @@ #define WEBKIT_PARAM_WRITABLE (static_cast<GParamFlags>(G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)) #define WEBKIT_PARAM_READWRITE (static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)) -#define COMPILE_ASSERT_MATCHING_ENUM(webkitName, webcoreName) \ - COMPILE_ASSERT(int(webkitName) == int(webcoreName), mismatchingEnums) - #define WEBKIT_DEFINE_ASYNC_DATA_STRUCT(structName) \ static structName* create##structName() \ { \ - structName* data = g_slice_new0(structName); \ + structName* data = static_cast<structName*>(fastZeroedMalloc(sizeof(structName))); \ new (data) structName(); \ return data; \ } \ static void destroy##structName(structName* data) \ { \ data->~structName(); \ - g_slice_free(structName, data); \ + fastFree(data); \ } #define WEBKIT_DEFINE_TYPE(TypeName, type_name, TYPE_PARENT) _WEBKIT_DEFINE_TYPE_EXTENDED(TypeName, type_name, TYPE_PARENT, 0, { }) @@ -118,10 +115,17 @@ GType type_name##_get_type(void) \ unsigned wkEventModifiersToGdkModifiers(WKEventModifiers); unsigned wkEventMouseButtonToWebKitMouseButton(WKEventMouseButton); +unsigned toGdkModifiers(WebKit::WebEvent::Modifiers); +WebKitNavigationType toWebKitNavigationType(WebCore::NavigationType); +unsigned toWebKitMouseButton(WebKit::WebMouseEvent::Button); +unsigned toWebKitError(unsigned webCoreError); +unsigned toWebCoreError(unsigned webKitError); enum SnapshotRegion { SnapshotRegionVisible, SnapshotRegionFullDocument }; +static const char networkCacheSubdirectory[] = "WebKitCache"; + #endif // WebKitPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.cpp deleted file mode 100644 index 72f91ec2e..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "WebKitRequestManagerClient.h" - -#include "WebKitWebContextPrivate.h" - -using namespace WebKit; - -static void startLoading(WKSoupCustomProtocolRequestManagerRef soupRequestManagerRef, uint64_t customProtocolID, WKURLRequestRef requestRef, const void* clientInfo) -{ - webkitWebContextStartLoadingCustomProtocol(WEBKIT_WEB_CONTEXT(clientInfo), customProtocolID, toImpl(requestRef)); -} - -static void stopLoading(WKSoupCustomProtocolRequestManagerRef, uint64_t customProtocolID, const void* clientInfo) -{ - webkitWebContextStopLoadingCustomProtocol(WEBKIT_WEB_CONTEXT(clientInfo), customProtocolID); -} - -void attachRequestManagerClientToContext(WebKitWebContext* webContext) -{ - WKSoupCustomProtocolRequestManagerClientV0 wkRequestManagerClient = { - { - 0, // version - webContext // clientInfo - }, - startLoading, - stopLoading - }; - WKSoupCustomProtocolRequestManagerSetClient(toAPI(webkitWebContextGetRequestManager(webContext)), &wkRequestManagerClient.base); -} - diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecision.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecision.cpp index b6054b814..69b241f85 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecision.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecision.cpp @@ -20,17 +20,16 @@ #include "config.h" #include "WebKitResponsePolicyDecision.h" -#include "APIURLRequest.h" -#include "APIURLResponse.h" #include "WebKitPolicyDecisionPrivate.h" #include "WebKitPrivate.h" #include "WebKitURIRequestPrivate.h" #include "WebKitURIResponsePrivate.h" #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; +using namespace WebCore; /** * SECTION: WebKitResponsePolicyDecision @@ -155,12 +154,13 @@ gboolean webkit_response_policy_decision_is_mime_type_supported(WebKitResponsePo return decision->priv->canShowMIMEType; } -WebKitResponsePolicyDecision* webkitResponsePolicyDecisionCreate(API::URLRequest* request, API::URLResponse* response, bool canShowMIMEType, WebFramePolicyListenerProxy* listener) +WebKitPolicyDecision* webkitResponsePolicyDecisionCreate(const ResourceRequest& request, const ResourceResponse& response, bool canShowMIMEType, WebFramePolicyListenerProxy* listener) { - WebKitResponsePolicyDecision* decision = WEBKIT_RESPONSE_POLICY_DECISION(g_object_new(WEBKIT_TYPE_RESPONSE_POLICY_DECISION, NULL)); - decision->priv->request = adoptGRef(webkitURIRequestCreateForResourceRequest(request->resourceRequest())); - decision->priv->response = adoptGRef(webkitURIResponseCreateForResourceResponse(response->resourceResponse())); - decision->priv->canShowMIMEType = canShowMIMEType; - webkitPolicyDecisionSetListener(WEBKIT_POLICY_DECISION(decision), listener); + WebKitResponsePolicyDecision* responseDecision = WEBKIT_RESPONSE_POLICY_DECISION(g_object_new(WEBKIT_TYPE_RESPONSE_POLICY_DECISION, nullptr)); + responseDecision->priv->request = adoptGRef(webkitURIRequestCreateForResourceRequest(request)); + responseDecision->priv->response = adoptGRef(webkitURIResponseCreateForResourceResponse(response)); + responseDecision->priv->canShowMIMEType = canShowMIMEType; + WebKitPolicyDecision* decision = WEBKIT_POLICY_DECISION(responseDecision); + webkitPolicyDecisionSetListener(decision, listener); return decision; } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecisionPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecisionPrivate.h index ff83a7df3..2ff91085b 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecisionPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecisionPrivate.h @@ -23,6 +23,6 @@ #include "WebKitPrivate.h" #include "WebKitResponsePolicyDecision.h" -WebKitResponsePolicyDecision* webkitResponsePolicyDecisionCreate(API::URLRequest*, API::URLResponse*, bool canShowMIMEType, WebKit::WebFramePolicyListenerProxy*); +WebKitPolicyDecision* webkitResponsePolicyDecisionCreate(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, bool canShowMIMEType, WebKit::WebFramePolicyListenerProxy*); #endif // WebKitResponsePolicyDecisionPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.cpp index 863665d71..5f9772407 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.cpp @@ -24,7 +24,7 @@ static WebKitScriptDialog* webkitScriptDialogCopy(WebKitScriptDialog* dialog) { - WebKitScriptDialog* copy = g_slice_new0(WebKitScriptDialog); + WebKitScriptDialog* copy = static_cast<WebKitScriptDialog*>(fastZeroedMalloc(sizeof(WebKitScriptDialog))); new (copy) WebKitScriptDialog(dialog); return copy; } @@ -32,7 +32,7 @@ static WebKitScriptDialog* webkitScriptDialogCopy(WebKitScriptDialog* dialog) static void webkitScriptDialogFree(WebKitScriptDialog* dialog) { dialog->~WebKitScriptDialog(); - g_slice_free(WebKitScriptDialog, dialog); + fastFree(dialog); } G_DEFINE_BOXED_TYPE(WebKitScriptDialog, webkit_script_dialog, webkitScriptDialogCopy, webkitScriptDialogFree) @@ -72,17 +72,17 @@ const char* webkit_script_dialog_get_message(WebKitScriptDialog* dialog) * @dialog: a #WebKitScriptDialog * @confirmed: whether user confirmed the dialog * - * This method is used for %WEBKIT_SCRIPT_DIALOG_CONFIRM dialogs when + * This method is used for %WEBKIT_SCRIPT_DIALOG_CONFIRM and %WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM dialogs when * #WebKitWebView::script-dialog signal is emitted to set whether the user * confirmed the dialog or not. The default implementation of #WebKitWebView::script-dialog - * signal sets %TRUE when the OK button is clicked and %FALSE otherwise. + * signal sets %TRUE when the OK or Stay buttons are clicked and %FALSE otherwise. * It's an error to use this method with a #WebKitScriptDialog that is not of type - * %WEBKIT_SCRIPT_DIALOG_CONFIRM. + * %WEBKIT_SCRIPT_DIALOG_CONFIRM or %WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM */ void webkit_script_dialog_confirm_set_confirmed(WebKitScriptDialog* dialog, gboolean confirmed) { g_return_if_fail(dialog); - g_return_if_fail(dialog->type == WEBKIT_SCRIPT_DIALOG_CONFIRM); + g_return_if_fail(dialog->type == WEBKIT_SCRIPT_DIALOG_CONFIRM || dialog->type == WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM); dialog->confirmed = confirmed; } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.h b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.h index cf88535ad..71095beed 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.h @@ -41,13 +41,16 @@ typedef struct _WebKitScriptDialog WebKitScriptDialog; * confirmation to the user. * @WEBKIT_SCRIPT_DIALOG_PROMPT: Prompt script dialog, used to ask * information to the user. + * @WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM: Before unload confirm dialog, + * used to ask confirmation to leave the current page to the user. Since 2.12 * * Enum values used for determining the type of #WebKitScriptDialog */ typedef enum { WEBKIT_SCRIPT_DIALOG_ALERT, WEBKIT_SCRIPT_DIALOG_CONFIRM, - WEBKIT_SCRIPT_DIALOG_PROMPT + WEBKIT_SCRIPT_DIALOG_PROMPT, + WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM } WebKitScriptDialogType; WEBKIT_API GType diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityManager.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityManager.cpp index 9b849a825..7245dd5ee 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityManager.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityManager.cpp @@ -20,9 +20,9 @@ #include "config.h" #include "WebKitSecurityManager.h" -#include "WebContext.h" #include "WebKitSecurityManagerPrivate.h" #include "WebKitWebContextPrivate.h" +#include "WebProcessPool.h" #include <WebCore/SchemeRegistry.h> using namespace WebKit; @@ -55,7 +55,7 @@ struct _WebKitSecurityManagerPrivate { WEBKIT_DEFINE_TYPE(WebKitSecurityManager, webkit_security_manager, G_TYPE_OBJECT) -static void webkit_security_manager_class_init(WebKitSecurityManagerClass* klass) +static void webkit_security_manager_class_init(WebKitSecurityManagerClass*) { } @@ -69,7 +69,7 @@ WebKitSecurityManager* webkitSecurityManagerCreate(WebKitWebContext* webContext) static void registerSecurityPolicyForURIScheme(WebKitSecurityManager* manager, const char* scheme, SecurityPolicy policy) { String urlScheme = String::fromUTF8(scheme); - WebContext* webContext = webkitWebContextGetContext(manager->priv->webContext); + auto& processPool = webkitWebContextGetProcessPool(manager->priv->webContext); // We keep the WebCore::SchemeRegistry of the UI process in sync with the // web process one, so that we can return the SecurityPolicy for @@ -77,27 +77,27 @@ static void registerSecurityPolicyForURIScheme(WebKitSecurityManager* manager, c switch (policy) { case SecurityPolicyLocal: WebCore::SchemeRegistry::registerURLSchemeAsLocal(urlScheme); - webContext->registerURLSchemeAsLocal(urlScheme); + processPool.registerURLSchemeAsLocal(urlScheme); break; case SecurityPolicyNoAccess: WebCore::SchemeRegistry::registerURLSchemeAsNoAccess(urlScheme); - webContext->registerURLSchemeAsNoAccess(urlScheme); + processPool.registerURLSchemeAsNoAccess(urlScheme); break; case SecurityPolicyDisplayIsolated: WebCore::SchemeRegistry::registerURLSchemeAsDisplayIsolated(urlScheme); - webContext->registerURLSchemeAsDisplayIsolated(urlScheme); + processPool.registerURLSchemeAsDisplayIsolated(urlScheme); break; case SecurityPolicySecure: WebCore::SchemeRegistry::registerURLSchemeAsSecure(urlScheme); - webContext->registerURLSchemeAsSecure(urlScheme); + processPool.registerURLSchemeAsSecure(urlScheme); break; case SecurityPolicyCORSEnabled: WebCore::SchemeRegistry::registerURLSchemeAsCORSEnabled(urlScheme); - webContext->registerURLSchemeAsCORSEnabled(urlScheme); + processPool.registerURLSchemeAsCORSEnabled(urlScheme); break; case SecurityPolicyEmptyDocument: WebCore::SchemeRegistry::registerURLSchemeAsEmptyDocument(urlScheme); - webContext->registerURLSchemeAsEmptyDocument(urlScheme); + processPool.registerURLSchemeAsEmptyDocument(urlScheme); break; } } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOrigin.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOrigin.cpp new file mode 100644 index 000000000..0a5ba63e7 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOrigin.cpp @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitSecurityOrigin.h" + +#include "WebKitSecurityOriginPrivate.h" +#include <WebCore/URL.h> +#include <wtf/text/CString.h> + +using namespace WebKit; + +/** + * SECTION: WebKitSecurityOrigin + * @Short_description: A security boundary for websites + * @Title: WebKitSecurityOrigin + * + * #WebKitSecurityOrigin is a representation of a security domain + * defined by websites. A security origin normally consists of a + * protocol, a hostname, and a port number. It is also possible for a + * security origin to be opaque, as defined by the HTML standard, in + * which case it has no associated protocol, host, or port. + * + * Websites with the same security origin can access each other's + * resources for client-side scripting or database access. + * + * Since: 2.16 + */ + +struct _WebKitSecurityOrigin { + _WebKitSecurityOrigin(Ref<WebCore::SecurityOrigin>&& coreSecurityOrigin) + : securityOrigin(WTFMove(coreSecurityOrigin)) + { + } + + Ref<WebCore::SecurityOrigin> securityOrigin; + CString protocol; + CString host; + int referenceCount { 1 }; +}; + +G_DEFINE_BOXED_TYPE(WebKitSecurityOrigin, webkit_security_origin, webkit_security_origin_ref, webkit_security_origin_unref) + +WebKitSecurityOrigin* webkitSecurityOriginCreate(Ref<WebCore::SecurityOrigin>&& coreSecurityOrigin) +{ + WebKitSecurityOrigin* origin = static_cast<WebKitSecurityOrigin*>(fastMalloc(sizeof(WebKitSecurityOrigin))); + new (origin) WebKitSecurityOrigin(WTFMove(coreSecurityOrigin)); + return origin; +} + +WebCore::SecurityOrigin& webkitSecurityOriginGetSecurityOrigin(WebKitSecurityOrigin* origin) +{ + ASSERT(origin); + return origin->securityOrigin.get(); +} + +/** + * webkit_security_origin_new: + * @protocol: The protocol for the new origin + * @host: The host for the new origin + * @port: The port number for the new origin, or 0 to indicate the + * default port for @protocol + * + * Create a new security origin from the provided protocol, host and + * port. + * + * Returns: (transfer full): A #WebKitSecurityOrigin. + * + * Since: 2.16 + */ +WebKitSecurityOrigin* webkit_security_origin_new(const gchar* protocol, const gchar* host, guint16 port) +{ + g_return_val_if_fail(protocol, nullptr); + g_return_val_if_fail(host, nullptr); + + std::optional<uint16_t> optionalPort; + if (port) + optionalPort = port; + + return webkitSecurityOriginCreate(WebCore::SecurityOrigin::create(String::fromUTF8(protocol), String::fromUTF8(host), optionalPort)); +} + +/** + * webkit_security_origin_new_for_uri: + * @uri: The URI for the new origin + * + * Create a new security origin from the provided URI. Components of + * @uri other than protocol, host, and port do not affect the created + * #WebKitSecurityOrigin. + * + * Returns: (transfer full): A #WebKitSecurityOrigin. + * + * Since: 2.16 + */ +WebKitSecurityOrigin* webkit_security_origin_new_for_uri(const gchar* uri) +{ + g_return_val_if_fail(uri, nullptr); + + return webkitSecurityOriginCreate(WebCore::SecurityOrigin::create(WebCore::URL(WebCore::URL(), String::fromUTF8(uri)))); +} + +/** + * webkit_security_origin_ref: + * @origin: a #WebKitSecurityOrigin + * + * Atomically increments the reference count of @origin by one. + * This function is MT-safe and may be called from any thread. + * + * Returns: The passed #WebKitSecurityOrigin + * + * Since: 2.16 + */ +WebKitSecurityOrigin* webkit_security_origin_ref(WebKitSecurityOrigin* origin) +{ + g_return_val_if_fail(origin, nullptr); + + g_atomic_int_inc(&origin->referenceCount); + return origin; +} + +/** + * webkit_security_origin_unref: + * @origin: A #WebKitSecurityOrigin + * + * Atomically decrements the reference count of @origin by one. + * If the reference count drops to 0, all memory allocated by + * #WebKitSecurityOrigin is released. This function is MT-safe and may be + * called from any thread. + * + * Since: 2.16 + */ +void webkit_security_origin_unref(WebKitSecurityOrigin* origin) +{ + g_return_if_fail(origin); + + if (g_atomic_int_dec_and_test(&origin->referenceCount)) { + origin->~WebKitSecurityOrigin(); + fastFree(origin); + } +} + +/** + * webkit_security_origin_get_protocol: + * @origin: a #WebKitSecurityOrigin + * + * Gets the protocol of @origin, or %NULL if @origin is opaque. + * + * Returns: (allow-none): The protocol of the #WebKitSecurityOrigin + * + * Since: 2.16 + */ +const gchar* webkit_security_origin_get_protocol(WebKitSecurityOrigin* origin) +{ + g_return_val_if_fail(origin, nullptr); + + if (origin->securityOrigin->protocol().isEmpty()) + return nullptr; + + if (origin->protocol.isNull()) + origin->protocol = origin->securityOrigin->protocol().utf8(); + return origin->protocol.data(); +} + +/** + * webkit_security_origin_get_host: + * @origin: a #WebKitSecurityOrigin + * + * Gets the hostname of @origin, or %NULL if @origin is opaque or if its + * protocol does not require a host component. + * + * Returns: (allow-none): The host of the #WebKitSecurityOrigin + * + * Since: 2.16 + */ +const gchar* webkit_security_origin_get_host(WebKitSecurityOrigin* origin) +{ + g_return_val_if_fail(origin, nullptr); + + if (origin->securityOrigin->host().isEmpty()) + return nullptr; + + if (origin->host.isNull()) + origin->host = origin->securityOrigin->host().utf8(); + return origin->host.data(); +} + +/** + * webkit_security_origin_get_port: + * @origin: a #WebKitSecurityOrigin + * + * Gets the port of @origin. This function will always return 0 if the + * port is the default port for the given protocol. For example, + * http://example.com has the same security origin as + * http://example.com:80, and this function will return 0 for a + * #WebKitSecurityOrigin constructed from either URI. It will also + * return 0 if @origin is opaque. + * + * Returns: The port of the #WebKitSecurityOrigin. + * + * Since: 2.16 + */ +guint16 webkit_security_origin_get_port(WebKitSecurityOrigin* origin) +{ + g_return_val_if_fail(origin, 0); + + return origin->securityOrigin->port().value_or(0); +} + +/** + * webkit_security_origin_is_opaque: + * @origin: a #WebKitSecurityOrigin + * + * Gets whether @origin is an opaque security origin, which does not + * possess an associated protocol, host, or port. + * + * Returns: %TRUE if @origin is opaque. + * + * Since: 2.16 + */ +gboolean webkit_security_origin_is_opaque(WebKitSecurityOrigin* origin) +{ + g_return_val_if_fail(origin, TRUE); + + return origin->securityOrigin->isUnique(); +} + +/** + * webkit_security_origin_to_string: + * @origin: a #WebKitSecurityOrigin + * + * Gets a string representation of @origin. The string representation + * is a valid URI with only protocol, host, and port components. It may + * be %NULL, but usually only if @origin is opaque. + * + * Returns: (allow-none) (transfer full): a URI representing @origin. + * + * Since: 2.16 + */ +gchar* webkit_security_origin_to_string(WebKitSecurityOrigin* origin) +{ + g_return_val_if_fail(origin, nullptr); + + CString cstring = origin->securityOrigin->toString().utf8(); + return cstring == "null" ? nullptr : g_strdup (cstring.data()); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOrigin.h b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOrigin.h new file mode 100644 index 000000000..6dca2b77e --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOrigin.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitSecurityOrigin_h +#define WebKitSecurityOrigin_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_SECURITY_ORIGIN (webkit_security_origin_get_type()) + +typedef struct _WebKitSecurityOrigin WebKitSecurityOrigin; + +WEBKIT_API GType +webkit_security_origin_get_type (void); + +WEBKIT_API WebKitSecurityOrigin * +webkit_security_origin_new (const gchar *protocol, + const gchar *host, + guint16 port); + +WEBKIT_API WebKitSecurityOrigin * +webkit_security_origin_new_for_uri (const gchar *uri); + +WEBKIT_API WebKitSecurityOrigin * +webkit_security_origin_ref (WebKitSecurityOrigin *origin); + +WEBKIT_API void +webkit_security_origin_unref (WebKitSecurityOrigin *origin); + +WEBKIT_API const gchar * +webkit_security_origin_get_protocol (WebKitSecurityOrigin *origin); + +WEBKIT_API const gchar * +webkit_security_origin_get_host (WebKitSecurityOrigin *origin); + +WEBKIT_API guint16 +webkit_security_origin_get_port (WebKitSecurityOrigin *origin); + +WEBKIT_API gboolean +webkit_security_origin_is_opaque (WebKitSecurityOrigin *origin); + +WEBKIT_API gchar * +webkit_security_origin_to_string (WebKitSecurityOrigin *origin); + +G_END_DECLS + +#endif /* WebKitSecurityOrigin_h */ diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOriginPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOriginPrivate.h new file mode 100644 index 000000000..cf580f967 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOriginPrivate.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "WebKitPrivate.h" +#include "WebKitSecurityOrigin.h" +#include <WebCore/SecurityOrigin.h> + +WebKitSecurityOrigin* webkitSecurityOriginCreate(Ref<WebCore::SecurityOrigin>&&); +WebCore::SecurityOrigin& webkitSecurityOriginGetSecurityOrigin(WebKitSecurityOrigin*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp index 7c49ccd82..83b70edee 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp @@ -31,18 +31,25 @@ #include "config.h" #include "WebKitSettings.h" -#include "ExperimentalFeatures.h" +#include "HardwareAccelerationManager.h" +#include "WebKitEnumTypes.h" #include "WebKitPrivate.h" #include "WebKitSettingsPrivate.h" -#include <WebCore/UserAgentGtk.h> +#include "WebPageProxy.h" +#include "WebPreferences.h" +#include <WebCore/UserAgent.h> #include <glib/gi18n-lib.h> #include <wtf/text/CString.h> +#if PLATFORM(WAYLAND) +#include <WebCore/PlatformDisplay.h> +#endif + using namespace WebKit; struct _WebKitSettingsPrivate { _WebKitSettingsPrivate() - : preferences(WebPreferences::create()) + : preferences(WebPreferences::create(String(), "WebKit2.", "WebKit2.")) { defaultFontFamily = preferences->standardFontFamily().utf8(); monospaceFontFamily = preferences->fixedFontFamily().utf8(); @@ -70,13 +77,12 @@ struct _WebKitSettingsPrivate { /** * SECTION:WebKitSettings - * @short_description: Control the behaviour of #WebKitWebView<!-- -->s - * @see_also: #WebKitWebViewGroup, #WebKitWebView + * @short_description: Control the behaviour of a #WebKitWebView * - * #WebKitSettings can be applied to a #WebKitWebViewGroup to control text charset, + * #WebKitSettings can be applied to a #WebKitWebView to control text charset, * color, font sizes, printing mode, script support, loading of images and various - * other things on the #WebKitWebView<!-- -->s of the group. - * After creation, a #WebKitSettings object contains default settings. + * other things on a #WebKitWebView. After creation, a #WebKitSettings object + * contains default settings. * * <informalexample><programlisting> * /<!-- -->* Disable JavaScript. *<!-- -->/ @@ -138,7 +144,10 @@ enum { PROP_ENABLE_WRITE_CONSOLE_MESSAGES_TO_STDOUT, PROP_ENABLE_MEDIA_STREAM, PROP_ENABLE_SPATIAL_NAVIGATION, - PROP_ENABLE_MEDIASOURCE + PROP_ENABLE_MEDIASOURCE, + PROP_ALLOW_FILE_ACCESS_FROM_FILE_URLS, + PROP_ALLOW_UNIVERSAL_ACCESS_FROM_FILE_URLS, + PROP_HARDWARE_ACCELERATION_POLICY, }; static void webKitSettingsConstructed(GObject* object) @@ -146,14 +155,6 @@ static void webKitSettingsConstructed(GObject* object) G_OBJECT_CLASS(webkit_settings_parent_class)->constructed(object); WebPreferences* prefs = WEBKIT_SETTINGS(object)->priv->preferences.get(); - ExperimentalFeatures features; - bool cssGridLayoutEnabled = features.isEnabled(ExperimentalFeatures::CSSGridLayout); - if (prefs->cssGridLayoutEnabled() != cssGridLayoutEnabled) - prefs->setCSSGridLayoutEnabled(cssGridLayoutEnabled); - bool regionBasedColumnsEnabled = features.isEnabled(ExperimentalFeatures::RegionBasedColumns); - if (prefs->regionBasedColumnsEnabled() != regionBasedColumnsEnabled) - prefs->setRegionBasedColumnsEnabled(regionBasedColumnsEnabled); - prefs->setShouldRespectImageOrientation(true); } @@ -232,7 +233,9 @@ static void webKitSettingsSetProperty(GObject* object, guint propId, const GValu webkit_settings_set_default_charset(settings, g_value_get_string(value)); break; case PROP_ENABLE_PRIVATE_BROWSING: + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; webkit_settings_set_enable_private_browsing(settings, g_value_get_boolean(value)); + G_GNUC_END_IGNORE_DEPRECATIONS; break; case PROP_ENABLE_DEVELOPER_EXTRAS: webkit_settings_set_enable_developer_extras(settings, g_value_get_boolean(value)); @@ -312,6 +315,15 @@ static void webKitSettingsSetProperty(GObject* object, guint propId, const GValu case PROP_ENABLE_MEDIASOURCE: webkit_settings_set_enable_mediasource(settings, g_value_get_boolean(value)); break; + case PROP_ALLOW_FILE_ACCESS_FROM_FILE_URLS: + webkit_settings_set_allow_file_access_from_file_urls(settings, g_value_get_boolean(value)); + break; + case PROP_ALLOW_UNIVERSAL_ACCESS_FROM_FILE_URLS: + webkit_settings_set_allow_universal_access_from_file_urls(settings, g_value_get_boolean(value)); + break; + case PROP_HARDWARE_ACCELERATION_POLICY: + webkit_settings_set_hardware_acceleration_policy(settings, static_cast<WebKitHardwareAccelerationPolicy>(g_value_get_enum(value))); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); break; @@ -393,7 +405,9 @@ static void webKitSettingsGetProperty(GObject* object, guint propId, GValue* val g_value_set_string(value, webkit_settings_get_default_charset(settings)); break; case PROP_ENABLE_PRIVATE_BROWSING: + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; g_value_set_boolean(value, webkit_settings_get_enable_private_browsing(settings)); + G_GNUC_END_IGNORE_DEPRECATIONS; break; case PROP_ENABLE_DEVELOPER_EXTRAS: g_value_set_boolean(value, webkit_settings_get_enable_developer_extras(settings)); @@ -467,7 +481,15 @@ static void webKitSettingsGetProperty(GObject* object, guint propId, GValue* val case PROP_ENABLE_MEDIASOURCE: g_value_set_boolean(value, webkit_settings_get_enable_mediasource(settings)); break; - + case PROP_ALLOW_FILE_ACCESS_FROM_FILE_URLS: + g_value_set_boolean(value, webkit_settings_get_allow_file_access_from_file_urls(settings)); + break; + case PROP_ALLOW_UNIVERSAL_ACCESS_FROM_FILE_URLS: + g_value_set_boolean(value, webkit_settings_get_allow_universal_access_from_file_urls(settings)); + break; + case PROP_HARDWARE_ACCELERATION_POLICY: + g_value_set_enum(value, webkit_settings_get_hardware_acceleration_policy(settings)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); break; @@ -665,7 +687,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:default-font-family: + * WebKitSettings:default-font-family: * * The font family to use as the default for content that does not specify a font. */ @@ -678,7 +700,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:monospace-font-family: + * WebKitSettings:monospace-font-family: * * The font family used as the default for content using a monospace font. * @@ -692,7 +714,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:serif-font-family: + * WebKitSettings:serif-font-family: * * The font family used as the default for content using a serif font. */ @@ -705,7 +727,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:sans-serif-font-family: + * WebKitSettings:sans-serif-font-family: * * The font family used as the default for content using a sans-serif font. */ @@ -718,7 +740,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:cursive-font-family: + * WebKitSettings:cursive-font-family: * * The font family used as the default for content using a cursive font. */ @@ -731,7 +753,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:fantasy-font-family: + * WebKitSettings:fantasy-font-family: * * The font family used as the default for content using a fantasy font. */ @@ -744,7 +766,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:pictograph-font-family: + * WebKitSettings:pictograph-font-family: * * The font family used as the default for content using a pictograph font. */ @@ -757,7 +779,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:default-font-size: + * WebKitSettings:default-font-size: * * The default font size in pixels to use for content displayed if * no font size is specified. @@ -771,7 +793,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:default-monospace-font-size: + * WebKitSettings:default-monospace-font-size: * * The default font size in pixels to use for content displayed in * monospace font if no font size is specified. @@ -785,7 +807,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:minimum-font-size: + * WebKitSettings:minimum-font-size: * * The minimum font size in points used to display text. This setting * controls the absolute smallest size. Values other than 0 can @@ -817,6 +839,8 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) * * Determines whether or not private browsing is enabled. Private browsing * will disable history, cache and form auto-fill for any pages visited. + * + * Deprecated: 2.16. Use #WebKitWebView:is-ephemeral or #WebKitWebContext:is-ephemeral instead. */ g_object_class_install_property(gObjectClass, PROP_ENABLE_PRIVATE_BROWSING, @@ -1191,7 +1215,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) * there is an element they might be trying to reach towards the right, and if * there are multiple elements, which element they probably wants. * - * Since: 2.3 + * Since: 2.4 */ g_object_class_install_property(gObjectClass, PROP_ENABLE_SPATIAL_NAVIGATION, @@ -1220,6 +1244,71 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) _("Whether MediaSource should be enabled."), FALSE, readWriteConstructParamFlags)); + + /** + * WebKitSettings:allow-file-access-from-file-urls: + * + * Whether file access is allowed from file URLs. By default, when + * something is loaded in a #WebKitWebView using a file URI, cross + * origin requests to other file resources are not allowed. This + * setting allows you to change that behaviour, so that it would be + * possible to do a XMLHttpRequest of a local file, for example. + * + * Since: 2.10 + */ + g_object_class_install_property(gObjectClass, + PROP_ALLOW_FILE_ACCESS_FROM_FILE_URLS, + g_param_spec_boolean("allow-file-access-from-file-urls", + _("Allow file access from file URLs"), + _("Whether file access is allowed from file URLs."), + FALSE, + readWriteConstructParamFlags)); + + /** + * WebKitSettings:allow-universal-access-from-file-urls: + * + * Whether or not JavaScript running in the context of a file scheme URL + * should be allowed to access content from any origin. By default, when + * something is loaded in a #WebKitWebView using a file scheme URL, + * access to the local file system and arbitrary local storage is not + * allowed. This setting allows you to change that behaviour, so that + * it would be possible to use local storage, for example. + * + * Since: 2.14 + */ + g_object_class_install_property(gObjectClass, + PROP_ALLOW_UNIVERSAL_ACCESS_FROM_FILE_URLS, + g_param_spec_boolean("allow-universal-access-from-file-urls", + _("Allow universal access from the context of file scheme URLs"), + _("Whether or not universal access is allowed from the context of file scheme URLs"), + FALSE, + readWriteConstructParamFlags)); + + /** + * WebKitSettings:hardware-acceleration-policy: + * + * The #WebKitHardwareAccelerationPolicy to decide how to enable and disable + * hardware acceleration. The default value %WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND + * enables the hardware acceleration when the web contents request it, disabling it again + * when no longer needed. It's possible to enfore hardware acceleration to be always enabled + * by using %WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS. And it's also posible to disable it + * completely using %WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER. Note that disabling hardware + * acceleration might cause some websites to not render correctly or consume more CPU. + * + * Note that changing this setting might not be possible if hardware acceleration is not + * supported by the hardware or the system. In that case you can get the value to know the + * actual policy being used, but changing the setting will not have any effect. + * + * Since: 2.16 + */ + g_object_class_install_property(gObjectClass, + PROP_HARDWARE_ACCELERATION_POLICY, + g_param_spec_enum("hardware-acceleration-policy", + _("Hardware Acceleration Policy"), + _("The policy to decide how to enable and disable hardware acceleration"), + WEBKIT_TYPE_HARDWARE_ACCELERATION_POLICY, + WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND, + readWriteConstructParamFlags)); } WebPreferences* webkitSettingsGetPreferences(WebKitSettings* settings) @@ -1231,7 +1320,7 @@ WebPreferences* webkitSettingsGetPreferences(WebKitSettings* settings) * webkit_settings_new: * * Creates a new #WebKitSettings instance with default values. It must - * be manually attached to a #WebKitWebViewGroup. + * be manually attached to a #WebKitWebView. * See also webkit_settings_new_with_settings(). * * Returns: a new #WebKitSettings instance. @@ -1248,7 +1337,7 @@ WebKitSettings* webkit_settings_new() * %NULL-terminated * * Creates a new #WebKitSettings instance with the given settings. It must - * be manually attached to a #WebKitWebViewGroup. + * be manually attached to a #WebKitWebView. * * Returns: a new #WebKitSettings instance. */ @@ -2090,6 +2179,8 @@ void webkit_settings_set_default_charset(WebKitSettings* settings, const gchar* * Get the #WebKitSettings:enable-private-browsing property. * * Returns: %TRUE If private browsing is enabled or %FALSE otherwise. + * + * Deprecated: 2.16. Use #WebKitWebView:is-ephemeral or #WebKitWebContext:is-ephemeral instead. */ gboolean webkit_settings_get_enable_private_browsing(WebKitSettings* settings) { @@ -2099,11 +2190,13 @@ gboolean webkit_settings_get_enable_private_browsing(WebKitSettings* settings) } /** - * webkit_settings_set_private_caret_browsing: + * webkit_settings_set_enable_private_browsing: * @settings: a #WebKitSettings * @enabled: Value to be set * * Set the #WebKitSettings:enable-private-browsing property. + * + * Deprecated: 2.16. Use #WebKitWebView:is-ephemeral or #WebKitWebContext:is-ephemeral instead. */ void webkit_settings_set_enable_private_browsing(WebKitSettings* settings, gboolean enabled) { @@ -2551,7 +2644,7 @@ gboolean webkit_settings_get_media_playback_requires_user_gesture(WebKitSettings { g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE); - return settings->priv->preferences->mediaPlaybackRequiresUserGesture(); + return settings->priv->preferences->requiresUserGestureForMediaPlayback(); } /** @@ -2566,11 +2659,11 @@ void webkit_settings_set_media_playback_requires_user_gesture(WebKitSettings* se g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); WebKitSettingsPrivate* priv = settings->priv; - bool currentValue = priv->preferences->mediaPlaybackRequiresUserGesture(); + bool currentValue = priv->preferences->requiresUserGestureForMediaPlayback(); if (currentValue == enabled) return; - priv->preferences->setMediaPlaybackRequiresUserGesture(enabled); + priv->preferences->setRequiresUserGestureForMediaPlayback(enabled); g_object_notify(G_OBJECT(settings), "media-playback-requires-user-gesture"); } @@ -2587,7 +2680,7 @@ gboolean webkit_settings_get_media_playback_allows_inline(WebKitSettings* settin { g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), TRUE); - return settings->priv->preferences->mediaPlaybackAllowsInline(); + return settings->priv->preferences->allowsInlineMediaPlayback(); } /** @@ -2602,11 +2695,11 @@ void webkit_settings_set_media_playback_allows_inline(WebKitSettings* settings, g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); WebKitSettingsPrivate* priv = settings->priv; - bool currentValue = priv->preferences->mediaPlaybackAllowsInline(); + bool currentValue = priv->preferences->allowsInlineMediaPlayback(); if (currentValue == enabled) return; - priv->preferences->setMediaPlaybackAllowsInline(enabled); + priv->preferences->setAllowsInlineMediaPlayback(enabled); g_object_notify(G_OBJECT(settings), "media-playback-allows-inline"); } @@ -2920,6 +3013,7 @@ void webkit_settings_set_enable_media_stream(WebKitSettings* settings, gboolean return; priv->preferences->setMediaStreamEnabled(enabled); + priv->preferences->setPeerConnectionEnabled(enabled); g_object_notify(G_OBJECT(settings), "enable-media-stream"); } @@ -3002,3 +3096,161 @@ void webkit_settings_set_enable_mediasource(WebKitSettings* settings, gboolean e priv->preferences->setMediaSourceEnabled(enabled); g_object_notify(G_OBJECT(settings), "enable-mediasource"); } + +/** + * webkit_settings_get_allow_file_access_from_file_urls: + * @settings: a #WebKitSettings + * + * Get the #WebKitSettings:allow-file-access-from-file-urls property. + * + * Returns: %TRUE If file access from file URLs is allowed or %FALSE otherwise. + * + * Since: 2.10 + */ +gboolean webkit_settings_get_allow_file_access_from_file_urls(WebKitSettings* settings) +{ + g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE); + + return settings->priv->preferences->allowFileAccessFromFileURLs(); +} + +/** + * webkit_settings_set_allow_file_access_from_file_urls: + * @settings: a #WebKitSettings + * @allowed: Value to be set + * + * Set the #WebKitSettings:allow-file-access-from-file-urls property. + * + * Since: 2.10 + */ +void webkit_settings_set_allow_file_access_from_file_urls(WebKitSettings* settings, gboolean allowed) +{ + g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); + + WebKitSettingsPrivate* priv = settings->priv; + if (priv->preferences->allowFileAccessFromFileURLs() == allowed) + return; + + priv->preferences->setAllowFileAccessFromFileURLs(allowed); + g_object_notify(G_OBJECT(settings), "allow-file-access-from-file-urls"); +} + +/** + * webkit_settings_get_allow_universal_access_from_file_urls: + * @settings: a #WebKitSettings + * + * Get the #WebKitSettings:allow-universal-access-from-file-urls property. + * + * Returns: %TRUE If universal access from file URLs is allowed or %FALSE otherwise. + * + * Since: 2.14 + */ +gboolean webkit_settings_get_allow_universal_access_from_file_urls(WebKitSettings* settings) +{ + g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE); + + return settings->priv->preferences->allowUniversalAccessFromFileURLs(); +} + +/** + * webkit_settings_set_allow_universal_access_from_file_urls: + * @settings: a #WebKitSettings + * @allowed: Value to be set + * + * Set the #WebKitSettings:allow-universal-access-from-file-urls property. + * + * Since: 2.14 + */ +void webkit_settings_set_allow_universal_access_from_file_urls(WebKitSettings* settings, gboolean allowed) +{ + g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); + + WebKitSettingsPrivate* priv = settings->priv; + if (priv->preferences->allowUniversalAccessFromFileURLs() == allowed) + return; + + priv->preferences->setAllowUniversalAccessFromFileURLs(allowed); + g_object_notify(G_OBJECT(settings), "allow-universal-access-from-file-urls"); +} + +/** + * webkit_settings_get_hardware_acceleration_policy: + * @settings: a #WebKitSettings + * + * Get the #WebKitSettings:hardware-acceleration-policy property. + * + * Return: a #WebKitHardwareAccelerationPolicy + * + * Since: 2.16 + */ +WebKitHardwareAccelerationPolicy webkit_settings_get_hardware_acceleration_policy(WebKitSettings* settings) +{ + g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND); + + WebKitSettingsPrivate* priv = settings->priv; + if (!priv->preferences->acceleratedCompositingEnabled()) + return WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER; + + if (priv->preferences->forceCompositingMode()) + return WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS; + + return WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND; +} + +/** + * webkit_settings_set_hardware_acceleration_policy: + * @settings: a #WebKitSettings + * @policy: a #WebKitHardwareAccelerationPolicy + * + * Set the #WebKitSettings:hardware-acceleration-policy property. + * + * Since: 2.16 + */ +void webkit_settings_set_hardware_acceleration_policy(WebKitSettings* settings, WebKitHardwareAccelerationPolicy policy) +{ + g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); + + WebKitSettingsPrivate* priv = settings->priv; + bool changed = false; + switch (policy) { + case WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS: + if (!HardwareAccelerationManager::singleton().canUseHardwareAcceleration()) + return; + if (!priv->preferences->acceleratedCompositingEnabled()) { + priv->preferences->setAcceleratedCompositingEnabled(true); + changed = true; + } + if (!priv->preferences->forceCompositingMode()) { + priv->preferences->setForceCompositingMode(true); + changed = true; + } + break; + case WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER: + if (HardwareAccelerationManager::singleton().forceHardwareAcceleration()) + return; + if (priv->preferences->acceleratedCompositingEnabled()) { + priv->preferences->setAcceleratedCompositingEnabled(false); + changed = true; + } + + if (priv->preferences->forceCompositingMode()) { + priv->preferences->setForceCompositingMode(false); + changed = true; + } + break; + case WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND: + if (!priv->preferences->acceleratedCompositingEnabled() && HardwareAccelerationManager::singleton().canUseHardwareAcceleration()) { + priv->preferences->setAcceleratedCompositingEnabled(true); + changed = true; + } + + if (priv->preferences->forceCompositingMode() && !HardwareAccelerationManager::singleton().forceHardwareAcceleration()) { + priv->preferences->setForceCompositingMode(false); + changed = true; + } + break; + } + + if (changed) + g_object_notify(G_OBJECT(settings), "hardware-acceleration-policy"); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h index 66e687f3d..7f6357787 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h @@ -47,6 +47,22 @@ G_BEGIN_DECLS #define WEBKIT_IS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_SETTINGS)) #define WEBKIT_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_SETTINGS, WebKitSettingsClass)) +/** + * WebKitHardwareAccelerationPolicy: + * @WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND: Hardware acceleration is enabled/disabled as request by web contents. + * @WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS: Hardware acceleration is always enabled, even for websites not requesting it. + * @WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER: Hardware acceleration is always disabled, even for websites requesting it. + * + * Enum values used for determining the hardware acceleration policy. + * + * Since: 2.16 + */ +typedef enum { + WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND, + WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS, + WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER +} WebKitHardwareAccelerationPolicy; + typedef struct _WebKitSettings WebKitSettings; typedef struct _WebKitSettingsClass WebKitSettingsClass; typedef struct _WebKitSettingsPrivate WebKitSettingsPrivate; @@ -236,10 +252,10 @@ WEBKIT_API void webkit_settings_set_default_charset (WebKitSettings *settings, const gchar *default_charset); -WEBKIT_API gboolean +WEBKIT_DEPRECATED gboolean webkit_settings_get_enable_private_browsing (WebKitSettings *settings); -WEBKIT_API void +WEBKIT_DEPRECATED void webkit_settings_set_enable_private_browsing (WebKitSettings *settings, gboolean enabled); @@ -414,6 +430,27 @@ WEBKIT_API void webkit_settings_set_enable_mediasource (WebKitSettings *settings, gboolean enabled); +WEBKIT_API gboolean +webkit_settings_get_allow_file_access_from_file_urls (WebKitSettings *settings); + +WEBKIT_API void +webkit_settings_set_allow_file_access_from_file_urls (WebKitSettings *settings, + gboolean allowed); + +WEBKIT_API gboolean +webkit_settings_get_allow_universal_access_from_file_urls (WebKitSettings *settings); + +WEBKIT_API void +webkit_settings_set_allow_universal_access_from_file_urls (WebKitSettings *settings, + gboolean allowed); + +WEBKIT_API WebKitHardwareAccelerationPolicy +webkit_settings_get_hardware_acceleration_policy (WebKitSettings *settings); + +WEBKIT_API void +webkit_settings_set_hardware_acceleration_policy (WebKitSettings *settings, + WebKitHardwareAccelerationPolicy policy); + G_END_DECLS #endif /* WebKitSettings_h */ diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.cpp deleted file mode 100644 index 69b4b091b..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 "WebKitTextChecker.h" - -#if ENABLE(SPELLCHECK) - -#include "WebKitPrivate.h" - -using namespace WebKit; - -static inline WebKitTextChecker* toTextChecker(const void* clientInfo) -{ - return static_cast<WebKitTextChecker*>(const_cast<void*>(clientInfo)); -} - -static bool continuousSpellCheckingEnabledCallback(const void* clientInfo) -{ - return toTextChecker(clientInfo)->isSpellCheckingEnabled(); -} - -static void setContinuousSpellCheckingEnabledCallback(bool enabled, const void* clientInfo) -{ - toTextChecker(clientInfo)->setSpellCheckingEnabled(enabled); -} - -static void checkSpellingOfStringCallback(uint64_t tag, WKStringRef text, int32_t* misspellingLocation, int32_t* misspellingLength, const void* clientInfo) -{ - toTextChecker(clientInfo)->checkSpellingOfString(toImpl(text)->string(), *misspellingLocation, *misspellingLength); -} - -static WKArrayRef guessesForWordCallback(uint64_t tag, WKStringRef word, const void* clientInfo) -{ - Vector<String> guesses = toTextChecker(clientInfo)->getGuessesForWord(toImpl(word)->string()); - if (guesses.isEmpty()) - return 0; - - WKMutableArrayRef wkSuggestions = WKMutableArrayCreate(); - for (Vector<String>::const_iterator iter = guesses.begin(); iter != guesses.end(); ++iter) { - WKRetainPtr<WKStringRef> wkSuggestion(AdoptWK, WKStringCreateWithUTF8CString(iter->utf8().data())); - WKArrayAppendItem(wkSuggestions, wkSuggestion.get()); - } - - return wkSuggestions; -} - -static void learnWordCallback(uint64_t tag, WKStringRef word, const void* clientInfo) -{ - toTextChecker(clientInfo)->learnWord(toImpl(word)->string()); -} - -static void ignoreWordCallback(uint64_t tag, WKStringRef word, const void* clientInfo) -{ - toTextChecker(clientInfo)->ignoreWord(toImpl(word)->string()); -} - -WebKitTextChecker::~WebKitTextChecker() -{ -} - -WebKitTextChecker::WebKitTextChecker() - : m_textChecker(WebCore::TextCheckerEnchant::create()) - , m_spellCheckingEnabled(false) -{ - WKTextCheckerClientV0 wkTextCheckerClient = { - { - 0, // version - this, // clientInfo - }, - 0, // continuousSpellCheckingAllowed - continuousSpellCheckingEnabledCallback, - setContinuousSpellCheckingEnabledCallback, - 0, // grammarCheckingEnabled - 0, // setGrammarCheckingEnabled - 0, // uniqueSpellDocumentTag - 0, // closeSpellDocumentWithTag - checkSpellingOfStringCallback, - 0, // checkGrammarOfString - 0, // spellingUIIsShowing - 0, // toggleSpellingUIIsShowing - 0, // updateSpellingUIWithMisspelledWord - 0, // updateSpellingUIWithGrammarString - guessesForWordCallback, - learnWordCallback, - ignoreWordCallback, - }; - WKTextCheckerSetClient(&wkTextCheckerClient.base); -} - -void WebKitTextChecker::checkSpellingOfString(const String& string, int& misspellingLocation, int& misspellingLength) -{ - m_textChecker->checkSpellingOfString(string, misspellingLocation, misspellingLength); -} - -Vector<String> WebKitTextChecker::getGuessesForWord(const String& word) -{ - return m_textChecker->getGuessesForWord(word); -} - -void WebKitTextChecker::learnWord(const String& word) -{ - m_textChecker->learnWord(word); -} - -void WebKitTextChecker::ignoreWord(const String& word) -{ - m_textChecker->ignoreWord(word); -} - -void WebKitTextChecker::setSpellCheckingEnabled(bool enabled) -{ - if (m_spellCheckingEnabled == enabled) - return; - m_spellCheckingEnabled = enabled; - - // We need to notify the Web process that this has changed. - WKTextCheckerContinuousSpellCheckingEnabledStateChanged(enabled); -} - -const char* const* WebKitTextChecker::getSpellCheckingLanguages() -{ - Vector<String> spellCheckingLanguages = m_textChecker->loadedSpellCheckingLanguages(); - if (spellCheckingLanguages.isEmpty()) - return 0; - - m_spellCheckingLanguages = adoptGRef(g_ptr_array_new_with_free_func(g_free)); - for (size_t i = 0; i < spellCheckingLanguages.size(); ++i) - g_ptr_array_add(m_spellCheckingLanguages.get(), g_strdup(spellCheckingLanguages[i].utf8().data())); - g_ptr_array_add(m_spellCheckingLanguages.get(), 0); - - return reinterpret_cast<char**>(m_spellCheckingLanguages->pdata); -} - -void WebKitTextChecker::setSpellCheckingLanguages(const char* const* languages) -{ - Vector<String> spellCheckingLanguages; - for (size_t i = 0; languages[i]; ++i) - spellCheckingLanguages.append(String::fromUTF8(languages[i])); - m_textChecker->updateSpellCheckingLanguages(spellCheckingLanguages); -} -#endif // ENABLE(SPELLCHECK) diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.h b/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.h deleted file mode 100644 index 45424c584..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef WebKitTextChecker_h -#define WebKitTextChecker_h - -#if ENABLE(SPELLCHECK) - -#include <WebCore/TextCheckerEnchant.h> -#include <wtf/FastMalloc.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/Vector.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/text/CString.h> - -class WebKitTextChecker { - WTF_MAKE_FAST_ALLOCATED; - -public: - static PassOwnPtr<WebKitTextChecker> create() { return adoptPtr(new WebKitTextChecker()); } - virtual ~WebKitTextChecker(); - - // For implementing TextCheckerClient. - bool isSpellCheckingEnabled() { return m_spellCheckingEnabled; } - void setSpellCheckingEnabled(bool enabled); - void checkSpellingOfString(const String& string, int& misspellingLocation, int& misspellingLength); - Vector<String> getGuessesForWord(const String& word); - void learnWord(const String& word); - void ignoreWord(const String& word); - - // To be called from WebKitWebContext only. - const char* const* getSpellCheckingLanguages(); - void setSpellCheckingLanguages(const char* const* spellCheckingLanguages); - -private: - WebKitTextChecker(); - - OwnPtr<WebCore::TextCheckerEnchant> m_textChecker; - GRefPtr<GPtrArray> m_spellCheckingLanguages; - bool m_spellCheckingEnabled; -}; - -#endif // ENABLE(SPELLCHECK) - -#endif // WebKitTextChecker_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp index 483b82786..9bca06f52 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp @@ -20,199 +20,197 @@ #include "config.h" #include "WebKitUIClient.h" +#include "APIUIClient.h" #include "WebKitFileChooserRequestPrivate.h" #include "WebKitGeolocationPermissionRequestPrivate.h" +#include "WebKitNavigationActionPrivate.h" +#include "WebKitNotificationPermissionRequestPrivate.h" #include "WebKitPrivate.h" +#include "WebKitURIRequestPrivate.h" +#include "WebKitUserMediaPermissionRequestPrivate.h" #include "WebKitWebViewBasePrivate.h" #include "WebKitWebViewPrivate.h" #include "WebKitWindowPropertiesPrivate.h" #include "WebPageProxy.h" #include <WebCore/GtkUtilities.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> using namespace WebKit; -static WKPageRef createNewPage(WKPageRef page, WKURLRequestRef, WKDictionaryRef wkWindowFeatures, WKEventModifiers, WKEventMouseButton, const void* clientInfo) -{ - return static_cast<WKPageRef>(toAPI(webkitWebViewCreateNewPage(WEBKIT_WEB_VIEW(clientInfo), toImpl(wkWindowFeatures)))); -} +class UIClient : public API::UIClient { +public: + explicit UIClient(WebKitWebView* webView) + : m_webView(webView) + { + } -static void showPage(WKPageRef page, const void* clientInfo) -{ - webkitWebViewReadyToShowPage(WEBKIT_WEB_VIEW(clientInfo)); -} +private: + PassRefPtr<WebPageProxy> createNewPage(WebPageProxy*, WebFrameProxy*, const WebCore::SecurityOriginData&, const WebCore::ResourceRequest& resourceRequest, const WebCore::WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData) override + { + GRefPtr<WebKitURIRequest> request = adoptGRef(webkitURIRequestCreateForResourceRequest(resourceRequest)); + WebKitNavigationAction navigationAction(request.get(), navigationActionData); + return webkitWebViewCreateNewPage(m_webView, windowFeatures, &navigationAction); + } -static void closePage(WKPageRef page, const void* clientInfo) -{ - webkitWebViewClosePage(WEBKIT_WEB_VIEW(clientInfo)); -} + void showPage(WebPageProxy*) override + { + webkitWebViewReadyToShowPage(m_webView); + } -static void runJavaScriptAlert(WKPageRef page, WKStringRef message, WKFrameRef, const void* clientInfo) -{ - webkitWebViewRunJavaScriptAlert(WEBKIT_WEB_VIEW(clientInfo), toImpl(message)->string().utf8()); -} + void close(WebPageProxy*) override + { + webkitWebViewClosePage(m_webView); + } -static bool runJavaScriptConfirm(WKPageRef page, WKStringRef message, WKFrameRef, const void* clientInfo) -{ - return webkitWebViewRunJavaScriptConfirm(WEBKIT_WEB_VIEW(clientInfo), toImpl(message)->string().utf8()); -} + void runJavaScriptAlert(WebPageProxy*, const String& message, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void ()>&& completionHandler) override + { + webkitWebViewRunJavaScriptAlert(m_webView, message.utf8()); + completionHandler(); + } -static WKStringRef runJavaScriptPrompt(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef, const void* clientInfo) -{ - CString result = webkitWebViewRunJavaScriptPrompt(WEBKIT_WEB_VIEW(clientInfo), toImpl(message)->string().utf8(), - toImpl(defaultValue)->string().utf8()); - return WKStringCreateWithUTF8CString(result.data()); -} + void runJavaScriptConfirm(WebPageProxy*, const String& message, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void (bool)>&& completionHandler) override + { + completionHandler(webkitWebViewRunJavaScriptConfirm(m_webView, message.utf8())); + } -static bool toolbarsAreVisible(WKPageRef page, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - return webkit_window_properties_get_toolbar_visible(windowProperties); -} + void runJavaScriptPrompt(WebPageProxy*, const String& message, const String& defaultValue, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void (const String&)>&& completionHandler) override + { + CString result = webkitWebViewRunJavaScriptPrompt(m_webView, message.utf8(), defaultValue.utf8()); + if (result.isNull()) { + completionHandler(String()); + return; + } -static void setToolbarsAreVisible(WKPageRef page, bool toolbarsVisible, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - webkitWindowPropertiesSetToolbarVisible(windowProperties, toolbarsVisible); -} + completionHandler(String::fromUTF8(result.data())); + } -static bool menuBarIsVisible(WKPageRef page, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - return webkit_window_properties_get_menubar_visible(windowProperties); -} + bool canRunBeforeUnloadConfirmPanel() const override { return true; } -static void setMenuBarIsVisible(WKPageRef page, bool menuBarVisible, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - webkitWindowPropertiesSetMenubarVisible(windowProperties, menuBarVisible); -} + void runBeforeUnloadConfirmPanel(WebPageProxy*, const String& message, WebFrameProxy*, Function<void (bool)>&& completionHandler) override + { + completionHandler(webkitWebViewRunJavaScriptBeforeUnloadConfirm(m_webView, message.utf8())); + } -static bool statusBarIsVisible(WKPageRef page, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - return webkit_window_properties_get_statusbar_visible(windowProperties); -} + void mouseDidMoveOverElement(WebPageProxy*, const WebHitTestResultData& data, WebEvent::Modifiers modifiers, API::Object*) override + { + webkitWebViewMouseTargetChanged(m_webView, data, toGdkModifiers(modifiers)); + } -static void setStatusBarIsVisible(WKPageRef page, bool statusBarVisible, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - webkitWindowPropertiesSetStatusbarVisible(windowProperties, statusBarVisible); -} + bool toolbarsAreVisible(WebPageProxy*) override + { + return webkit_window_properties_get_toolbar_visible(webkit_web_view_get_window_properties(m_webView)); + } -static bool isResizable(WKPageRef page, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - return webkit_window_properties_get_resizable(windowProperties); -} + void setToolbarsAreVisible(WebPageProxy*, bool visible) override + { + webkitWindowPropertiesSetToolbarVisible(webkit_web_view_get_window_properties(m_webView), visible); + } -static void setIsResizable(WKPageRef page, bool resizable, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - webkitWindowPropertiesSetResizable(windowProperties, resizable); -} + bool menuBarIsVisible(WebPageProxy*) override + { + return webkit_window_properties_get_menubar_visible(webkit_web_view_get_window_properties(m_webView)); + } -static WKRect getWindowFrame(WKPageRef page, const void* clientInfo) -{ - GdkRectangle geometry = { 0, 0, 0, 0 }; - GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(clientInfo)); - if (WebCore::widgetIsOnscreenToplevelWindow(window) && gtk_widget_get_visible(window)) { - gtk_window_get_position(GTK_WINDOW(window), &geometry.x, &geometry.y); - gtk_window_get_size(GTK_WINDOW(window), &geometry.width, &geometry.height); + void setMenuBarIsVisible(WebPageProxy*, bool visible) override + { + webkitWindowPropertiesSetToolbarVisible(webkit_web_view_get_window_properties(m_webView), visible); } - return WKRectMake(geometry.x, geometry.y, geometry.width, geometry.height); -} -static void setWindowFrame(WKPageRef page, WKRect frame, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - GdkRectangle geometry = { static_cast<int>(frame.origin.x), static_cast<int>(frame.origin.y), - static_cast<int>(frame.size.width), static_cast<int>(frame.size.height) }; - webkitWindowPropertiesSetGeometry(windowProperties, &geometry); -} + bool statusBarIsVisible(WebPageProxy*) override + { + return webkit_window_properties_get_statusbar_visible(webkit_web_view_get_window_properties(m_webView)); + } -static void mouseDidMoveOverElement(WKPageRef page, WKHitTestResultRef hitTestResult, WKEventModifiers modifiers, WKTypeRef userData, const void* clientInfo) -{ - webkitWebViewMouseTargetChanged(WEBKIT_WEB_VIEW(clientInfo), toImpl(hitTestResult), wkEventModifiersToGdkModifiers(modifiers)); -} + void setStatusBarIsVisible(WebPageProxy*, bool visible) override + { + webkitWindowPropertiesSetStatusbarVisible(webkit_web_view_get_window_properties(m_webView), visible); + } -static void printFrame(WKPageRef page, WKFrameRef frame, const void*) -{ - webkitWebViewPrintFrame(WEBKIT_WEB_VIEW(toImpl(page)->viewWidget()), toImpl(frame)); -} + bool isResizable(WebPageProxy*) override + { + return webkit_window_properties_get_resizable(webkit_web_view_get_window_properties(m_webView)); + } -static void runOpenPanel(WKPageRef page, WKFrameRef frame, WKOpenPanelParametersRef parameters, WKOpenPanelResultListenerRef listener, const void *clientInfo) -{ - GRefPtr<WebKitFileChooserRequest> request = adoptGRef(webkitFileChooserRequestCreate(toImpl(parameters), toImpl(listener))); - webkitWebViewRunFileChooserRequest(WEBKIT_WEB_VIEW(clientInfo), request.get()); -} + void setIsResizable(WebPageProxy*, bool resizable) override + { + webkitWindowPropertiesSetResizable(webkit_web_view_get_window_properties(m_webView), resizable); + } -static void decidePolicyForGeolocationPermissionRequest(WKPageRef, WKFrameRef, WKSecurityOriginRef, WKGeolocationPermissionRequestRef request, const void* clientInfo) -{ - GRefPtr<WebKitGeolocationPermissionRequest> geolocationPermissionRequest = adoptGRef(webkitGeolocationPermissionRequestCreate(toImpl(request))); - webkitWebViewMakePermissionRequest(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_PERMISSION_REQUEST(geolocationPermissionRequest.get())); -} + void setWindowFrame(WebPageProxy*, const WebCore::FloatRect& frame) override + { + GdkRectangle geometry = WebCore::IntRect(frame); + webkitWindowPropertiesSetGeometry(webkit_web_view_get_window_properties(m_webView), &geometry); + } -static void runModal(WKPageRef page, const void* clientInfo) -{ - webkitWebViewRunAsModal(WEBKIT_WEB_VIEW(clientInfo)); -} + WebCore::FloatRect windowFrame(WebPageProxy*) override + { + GdkRectangle geometry = { 0, 0, 0, 0 }; + GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(m_webView)); + if (WebCore::widgetIsOnscreenToplevelWindow(window) && gtk_widget_get_visible(window)) { + gtk_window_get_position(GTK_WINDOW(window), &geometry.x, &geometry.y); + gtk_window_get_size(GTK_WINDOW(window), &geometry.width, &geometry.height); + } + return WebCore::FloatRect(geometry); + } + + void exceededDatabaseQuota(WebPageProxy*, WebFrameProxy*, API::SecurityOrigin*, const String&, const String&, unsigned long long /*currentQuota*/, unsigned long long /*currentOriginUsage*/, unsigned long long /*currentDatabaseUsage*/, unsigned long long /*expectedUsage*/, Function<void (unsigned long long)>&& completionHandler) override + { + static const unsigned long long defaultQuota = 5 * 1024 * 1204; // 5 MB + // FIXME: Provide API for this. + completionHandler(defaultQuota); + } + + bool runOpenPanel(WebPageProxy*, WebFrameProxy*, const WebCore::SecurityOriginData&, API::OpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener) override + { + GRefPtr<WebKitFileChooserRequest> request = adoptGRef(webkitFileChooserRequestCreate(parameters, listener)); + webkitWebViewRunFileChooserRequest(m_webView, request.get()); + return true; + } + + bool decidePolicyForGeolocationPermissionRequest(WebPageProxy*, WebFrameProxy*, API::SecurityOrigin*, GeolocationPermissionRequestProxy* permissionRequest) override + { + GRefPtr<WebKitGeolocationPermissionRequest> geolocationPermissionRequest = adoptGRef(webkitGeolocationPermissionRequestCreate(permissionRequest)); + webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(geolocationPermissionRequest.get())); + return true; + } + + bool decidePolicyForUserMediaPermissionRequest(WebPageProxy&, WebFrameProxy&, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionRequestProxy& permissionRequest) override + { + GRefPtr<WebKitUserMediaPermissionRequest> userMediaPermissionRequest = adoptGRef(webkitUserMediaPermissionRequestCreate(permissionRequest, userMediaDocumentOrigin, topLevelDocumentOrigin)); + webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(userMediaPermissionRequest.get())); + return true; + } + + bool decidePolicyForNotificationPermissionRequest(WebPageProxy*, API::SecurityOrigin*, NotificationPermissionRequest* permissionRequest) override + { + GRefPtr<WebKitNotificationPermissionRequest> notificationPermissionRequest = adoptGRef(webkitNotificationPermissionRequestCreate(permissionRequest)); + webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(notificationPermissionRequest.get())); + return true; + } + + void printFrame(WebPageProxy*, WebFrameProxy* frame) override + { + webkitWebViewPrintFrame(m_webView, frame); + } + + bool canRunModal() const override { return true; } + + void runModal(WebPageProxy*) override + { + webkitWebViewRunAsModal(m_webView); + } + + void isPlayingAudioDidChange(WebPageProxy&) override + { + webkitWebViewIsPlayingAudioChanged(m_webView); + } + + WebKitWebView* m_webView; +}; void attachUIClientToView(WebKitWebView* webView) { - WKPageUIClientV2 wkUIClient = { - { - 2, // version - webView, // clientInfo - }, - 0, // createNewPage_deprecatedForUseWithV0 - showPage, - closePage, - 0, // takeFocus - 0, // focus - 0, // unfocus - runJavaScriptAlert, - runJavaScriptConfirm, - runJavaScriptPrompt, - 0, // setStatusText - 0, // mouseDidMoveOverElement_deprecatedForUseWithV0 - 0, // missingPluginButtonClicked - 0, // didNotHandleKeyEvent - 0, // didNotHandleWheelEvent - toolbarsAreVisible, - setToolbarsAreVisible, - menuBarIsVisible, - setMenuBarIsVisible, - statusBarIsVisible, - setStatusBarIsVisible, - isResizable, - setIsResizable, - getWindowFrame, - setWindowFrame, - 0, // runBeforeUnloadConfirmPanel - 0, // didDraw - 0, // pageDidScroll - 0, // exceededDatabaseQuota - runOpenPanel, - decidePolicyForGeolocationPermissionRequest, - 0, // headerHeight - 0, // footerHeight - 0, // drawHeader - 0, // drawFooter - printFrame, - runModal, - 0, // didCompleteRubberBandForMainFrame - 0, // saveDataToFileInDownloadsFolder - 0, // shouldInterruptJavaScript - createNewPage, - mouseDidMoveOverElement, - 0, // decidePolicyForNotificationPermissionRequest - 0, // unavailablePluginButtonClicked - 0, // showColorPicker - 0, // hideColorPicker - 0, // pluginLoadPolicy - }; - WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); - WKPageSetPageUIClient(wkPage, &wkUIClient.base); + WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)); + page->setUIClient(std::make_unique<UIClient>(webView)); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.cpp index 2c59cd868..e2ff04d19 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.cpp @@ -48,6 +48,7 @@ using namespace WebCore; struct _WebKitURIRequestPrivate { WebCore::ResourceRequest resourceRequest; CString uri; + const char* httpMethod; GUniquePtr<SoupMessageHeaders> httpHeaders; }; @@ -171,6 +172,32 @@ SoupMessageHeaders* webkit_uri_request_get_http_headers(WebKitURIRequest* reques return request->priv->httpHeaders.get(); } +/** + * webkit_uri_request_get_http_method: + * @request: a #WebKitURIRequest + * + * Get the HTTP method of the #WebKitURIRequest. + * + * Returns: the HTTP method of the #WebKitURIRequest or %NULL if @request is not + * an HTTP request. + * + * Since: 2.12 + */ +const gchar* webkit_uri_request_get_http_method(WebKitURIRequest* request) +{ + g_return_val_if_fail(WEBKIT_IS_URI_REQUEST(request), nullptr); + + if (!request->priv->resourceRequest.url().protocolIsInHTTPFamily()) + return nullptr; + + if (request->priv->resourceRequest.httpMethod().isEmpty()) + return nullptr; + + if (!request->priv->httpMethod) + request->priv->httpMethod = g_intern_string(request->priv->resourceRequest.httpMethod().utf8().data()); + return request->priv->httpMethod; +} + WebKitURIRequest* webkitURIRequestCreateForResourceRequest(const ResourceRequest& resourceRequest) { WebKitURIRequest* uriRequest = WEBKIT_URI_REQUEST(g_object_new(WEBKIT_TYPE_URI_REQUEST, NULL)); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.h b/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.h index cac3b332b..10cf63489 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.h @@ -70,6 +70,9 @@ WEBKIT_API void webkit_uri_request_set_uri (WebKitURIRequest *request, const gchar *uri); +WEBKIT_API const gchar * +webkit_uri_request_get_http_method (WebKitURIRequest *request); + WEBKIT_API SoupMessageHeaders * webkit_uri_request_get_http_headers (WebKitURIRequest *request); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.cpp index 20ab248a5..b85fc4300 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.cpp @@ -22,6 +22,7 @@ #include "WebKitPrivate.h" #include "WebKitURIResponsePrivate.h" +#include <WebCore/GUniquePtrSoup.h> #include <glib/gi18n-lib.h> #include <wtf/text/CString.h> @@ -46,7 +47,8 @@ enum { PROP_STATUS_CODE, PROP_CONTENT_LENGTH, PROP_MIME_TYPE, - PROP_SUGGESTED_FILENAME + PROP_SUGGESTED_FILENAME, + PROP_HTTP_HEADERS }; struct _WebKitURIResponsePrivate { @@ -54,6 +56,7 @@ struct _WebKitURIResponsePrivate { CString uri; CString mimeType; CString suggestedFilename; + GUniquePtr<SoupMessageHeaders> httpHeaders; }; WEBKIT_DEFINE_TYPE(WebKitURIResponse, webkit_uri_response, G_TYPE_OBJECT) @@ -78,6 +81,9 @@ static void webkitURIResponseGetProperty(GObject* object, guint propId, GValue* case PROP_SUGGESTED_FILENAME: g_value_set_string(value, webkit_uri_response_get_suggested_filename(response)); break; + case PROP_HTTP_HEADERS: + g_value_set_boxed(value, webkit_uri_response_get_http_headers(response)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); } @@ -151,6 +157,23 @@ static void webkit_uri_response_class_init(WebKitURIResponseClass* responseClass _("The suggested filename for the URI response"), 0, WEBKIT_PARAM_READABLE)); + + /** + * WebKitURIResponse:http-headers: + * + * The HTTP headers of the response, or %NULL if the response is not an HTTP response. + * + * Since: 2.6 + */ + g_object_class_install_property( + objectClass, + PROP_HTTP_HEADERS, + g_param_spec_boxed( + "http-headers", + _("HTTP Headers"), + _("The The HTTP headers of the response"), + SOUP_TYPE_MESSAGE_HEADERS, + WEBKIT_PARAM_READABLE)); } /** @@ -237,6 +260,31 @@ const gchar* webkit_uri_response_get_suggested_filename(WebKitURIResponse* respo return response->priv->suggestedFilename.data(); } +/** + * webkit_uri_response_get_http_headers: + * @response: a #WebKitURIResponse + * + * Get the HTTP headers of a #WebKitURIResponse as a #SoupMessageHeaders. + * + * Returns: (transfer none): a #SoupMessageHeaders with the HTTP headers of @response + * or %NULL if @response is not an HTTP response. + * Since: 2.6 + */ +SoupMessageHeaders* webkit_uri_response_get_http_headers(WebKitURIResponse* response) +{ + g_return_val_if_fail(WEBKIT_IS_URI_RESPONSE(response), nullptr); + + if (response->priv->httpHeaders) + return response->priv->httpHeaders.get(); + + if (!response->priv->resourceResponse.url().protocolIsInHTTPFamily()) + return nullptr; + + response->priv->httpHeaders.reset(soup_message_headers_new(SOUP_MESSAGE_HEADERS_RESPONSE)); + response->priv->resourceResponse.updateSoupMessageHeaders(response->priv->httpHeaders.get()); + return response->priv->httpHeaders.get(); +} + WebKitURIResponse* webkitURIResponseCreateForResourceResponse(const WebCore::ResourceResponse& resourceResponse) { WebKitURIResponse* uriResponse = WEBKIT_URI_RESPONSE(g_object_new(WEBKIT_TYPE_URI_RESPONSE, NULL)); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.h b/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.h index d43eca13f..67316165f 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.h @@ -25,6 +25,7 @@ #define WebKitURIResponse_h #include <gio/gio.h> +#include <libsoup/soup.h> #include <webkit2/WebKitDefines.h> G_BEGIN_DECLS @@ -74,6 +75,9 @@ webkit_uri_response_get_mime_type (WebKitURIResponse *response); WEBKIT_API const gchar * webkit_uri_response_get_suggested_filename (WebKitURIResponse *response); +WEBKIT_API SoupMessageHeaders * +webkit_uri_response_get_http_headers (WebKitURIResponse *response); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequest.cpp index 6d8c68418..59bdb930d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequest.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequest.cpp @@ -21,6 +21,7 @@ #include "WebKitURISchemeRequest.h" #include "APIData.h" +#include "WebKitPrivate.h" #include "WebKitURISchemeRequestPrivate.h" #include "WebKitWebContextPrivate.h" #include "WebKitWebView.h" @@ -28,10 +29,11 @@ #include <WebCore/GUniquePtrSoup.h> #include <WebCore/ResourceError.h> #include <libsoup/soup.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; +using namespace WebCore; /** * SECTION: WebKitURISchemeRequest @@ -53,7 +55,7 @@ static const unsigned int gReadBufferSize = 8192; struct _WebKitURISchemeRequestPrivate { WebKitWebContext* webContext; - RefPtr<WebSoupCustomProtocolRequestManager> webRequestManager; + CustomProtocolManagerProxy* manager; RefPtr<WebPageProxy> initiatingPage; uint64_t requestID; CString uri; @@ -69,25 +71,35 @@ struct _WebKitURISchemeRequestPrivate { WEBKIT_DEFINE_TYPE(WebKitURISchemeRequest, webkit_uri_scheme_request, G_TYPE_OBJECT) -static void webkit_uri_scheme_request_class_init(WebKitURISchemeRequestClass* requestClass) +static void webkit_uri_scheme_request_class_init(WebKitURISchemeRequestClass*) { } -WebKitURISchemeRequest* webkitURISchemeRequestCreate(uint64_t requestID, WebKitWebContext* webContext, API::URLRequest* urlRequest) +WebKitURISchemeRequest* webkitURISchemeRequestCreate(uint64_t requestID, WebKitWebContext* webContext, const ResourceRequest& resourceRequest, CustomProtocolManagerProxy& manager) { - WebKitURISchemeRequest* request = WEBKIT_URI_SCHEME_REQUEST(g_object_new(WEBKIT_TYPE_URI_SCHEME_REQUEST, NULL)); + WebKitURISchemeRequest* request = WEBKIT_URI_SCHEME_REQUEST(g_object_new(WEBKIT_TYPE_URI_SCHEME_REQUEST, nullptr)); request->priv->webContext = webContext; - request->priv->webRequestManager = webkitWebContextGetRequestManager(webContext); - request->priv->uri = urlRequest->resourceRequest().url().string().utf8(); - request->priv->initiatingPage = WebProcessProxy::webPage(urlRequest->resourceRequest().initiatingPageID()); + request->priv->manager = &manager; + request->priv->uri = resourceRequest.url().string().utf8(); + request->priv->initiatingPage = WebProcessProxy::webPage(resourceRequest.initiatingPageID()); request->priv->requestID = requestID; return request; } void webkitURISchemeRequestCancel(WebKitURISchemeRequest* request) { - if (request->priv->cancellable.get()) - g_cancellable_cancel(request->priv->cancellable.get()); + g_cancellable_cancel(request->priv->cancellable.get()); +} + +CustomProtocolManagerProxy* webkitURISchemeRequestGetManager(WebKitURISchemeRequest* request) +{ + return request->priv->manager; +} + +void webkitURISchemeRequestInvalidate(WebKitURISchemeRequest* request) +{ + request->priv->manager = nullptr; + webkitURISchemeRequestCancel(request); } /** @@ -158,29 +170,39 @@ WebKitWebView* webkit_uri_scheme_request_get_web_view(WebKitURISchemeRequest* re static void webkitURISchemeRequestReadCallback(GInputStream* inputStream, GAsyncResult* result, WebKitURISchemeRequest* schemeRequest) { GRefPtr<WebKitURISchemeRequest> request = adoptGRef(schemeRequest); + WebKitURISchemeRequestPrivate* priv = request->priv; GUniqueOutPtr<GError> error; gssize bytesRead = g_input_stream_read_finish(inputStream, result, &error.outPtr()); + if (!priv->manager) { + webkitWebContextDidFinishLoadingCustomProtocol(priv->webContext, priv->requestID); + return; + } + if (bytesRead == -1) { webkit_uri_scheme_request_finish_error(request.get(), error.get()); return; } - WebKitURISchemeRequestPrivate* priv = request->priv; - RefPtr<API::Data> webData = API::Data::create(reinterpret_cast<const unsigned char*>(priv->readBuffer), bytesRead); + // Need to check the stream before proceeding as it can be cancelled if finish_error + // was previously call, which won't be detected by g_input_stream_read_finish(). + if (!request->priv->stream) + return; + + auto webData = IPC::DataReference(reinterpret_cast<const uint8_t*>(priv->readBuffer), bytesRead); if (!priv->bytesRead) { // First chunk read. In case of empty reply an empty API::Data is sent to the networking process. - WebCore::ResourceResponse response(WebCore::URL(WebCore::URL(), String::fromUTF8(priv->uri)), String::fromUTF8(priv->mimeType.data()), - priv->streamLength, emptyString(), emptyString()); - priv->webRequestManager->didReceiveResponse(priv->requestID, response); - priv->webRequestManager->didLoadData(priv->requestID, webData.get()); + ResourceResponse response(URL(URL(), String::fromUTF8(priv->uri)), String::fromUTF8(priv->mimeType.data()), + priv->streamLength, emptyString()); + priv->manager->didReceiveResponse(priv->requestID, response, 0); + priv->manager->didLoadData(priv->requestID, webData); } else if (bytesRead || (!bytesRead && !priv->streamLength)) { // Subsequent chunk read. We only send an empty API::Data to the networking process when stream length is unknown. - priv->webRequestManager->didLoadData(priv->requestID, webData.get()); + priv->manager->didLoadData(priv->requestID, webData); } if (!bytesRead) { - priv->webRequestManager->didFinishLoading(request->priv->requestID); - webkitWebContextDidFinishLoadingCustomProtocol(request->priv->webContext, request->priv->requestID); + priv->manager->didFinishLoading(priv->requestID); + webkitWebContextDidFinishLoadingCustomProtocol(priv->webContext, priv->requestID); return; } @@ -229,8 +251,11 @@ void webkit_uri_scheme_request_finish_error(WebKitURISchemeRequest* request, GEr g_return_if_fail(error); WebKitURISchemeRequestPrivate* priv = request->priv; + if (!webkitWebContextIsLoadingCustomProtocol(priv->webContext, priv->requestID)) + return; - WebCore::ResourceError resourceError(g_quark_to_string(error->domain), error->code, priv->uri.data(), String::fromUTF8(error->message)); - priv->webRequestManager->didFailWithError(priv->requestID, resourceError); + priv->stream = nullptr; + ResourceError resourceError(g_quark_to_string(error->domain), toWebCoreError(error->code), URL(priv->soupURI.get()), String::fromUTF8(error->message)); + priv->manager->didFailWithError(priv->requestID, resourceError); webkitWebContextDidFinishLoadingCustomProtocol(priv->webContext, priv->requestID); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequestPrivate.h index c72fa185e..47bb8c272 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequestPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequestPrivate.h @@ -20,11 +20,15 @@ #ifndef WebKitURISchemeRequestPrivate_h #define WebKitURISchemeRequestPrivate_h +#include "CustomProtocolManagerProxy.h" #include "WebKitPrivate.h" #include "WebKitURISchemeRequest.h" #include "WebKitWebContext.h" +#include <WebCore/ResourceRequest.h> -WebKitURISchemeRequest* webkitURISchemeRequestCreate(uint64_t requestID, WebKitWebContext*, API::URLRequest*); +WebKitURISchemeRequest* webkitURISchemeRequestCreate(uint64_t requestID, WebKitWebContext*, const WebCore::ResourceRequest&, WebKit::CustomProtocolManagerProxy&); void webkitURISchemeRequestCancel(WebKitURISchemeRequest*); +WebKit::CustomProtocolManagerProxy* webkitURISchemeRequestGetManager(WebKitURISchemeRequest*); +void webkitURISchemeRequestInvalidate(WebKitURISchemeRequest*); #endif // WebKitURISchemeRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserContent.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContent.cpp new file mode 100644 index 000000000..6fac63c6f --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContent.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitUserContent.h" + +#include "WebKitPrivate.h" +#include "WebKitUserContentPrivate.h" +#include <wtf/text/CString.h> + +using namespace WebCore; + +/** + * SECTION:WebKitUserContent + * @short_description: Defines user content types which affect web pages. + * @title: User content + * + * See also: #WebKitUserContentManager + * + * Since: 2.6 + */ + +static inline UserContentInjectedFrames toUserContentInjectedFrames(WebKitUserContentInjectedFrames injectedFrames) +{ + switch (injectedFrames) { + case WEBKIT_USER_CONTENT_INJECT_TOP_FRAME: + return InjectInTopFrameOnly; + case WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES: + return InjectInAllFrames; + default: + ASSERT_NOT_REACHED(); + return InjectInAllFrames; + } +} + +static inline UserStyleLevel toUserStyleLevel(WebKitUserStyleLevel styleLevel) +{ + switch (styleLevel) { + case WEBKIT_USER_STYLE_LEVEL_USER: + return UserStyleUserLevel; + case WEBKIT_USER_STYLE_LEVEL_AUTHOR: + return UserStyleAuthorLevel; + default: + ASSERT_NOT_REACHED(); + return UserStyleAuthorLevel; + } +} + +static inline UserScriptInjectionTime toUserScriptInjectionTime(WebKitUserScriptInjectionTime injectionTime) +{ + switch (injectionTime) { + case WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START: + return InjectAtDocumentStart; + case WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END: + return InjectAtDocumentEnd; + default: + ASSERT_NOT_REACHED(); + return InjectAtDocumentStart; + } +} + +static inline Vector<String> toStringVector(const char* const* strv) +{ + if (!strv) + return Vector<String>(); + + Vector<String> result; + for (auto str = strv; *str; ++str) + result.append(String::fromUTF8(*str)); + return result; +} + +struct _WebKitUserStyleSheet { + _WebKitUserStyleSheet(const gchar* source, WebKitUserContentInjectedFrames injectedFrames, WebKitUserStyleLevel level, const char* const* whitelist, const char* const* blacklist) + : userStyleSheet(adoptRef(new API::UserStyleSheet(UserStyleSheet { + String::fromUTF8(source), URL { }, + toStringVector(whitelist), toStringVector(blacklist), + toUserContentInjectedFrames(injectedFrames), + toUserStyleLevel(level) }, API::UserContentWorld::normalWorld()))) + , referenceCount(1) + { + } + + RefPtr<API::UserStyleSheet> userStyleSheet; + int referenceCount; +}; + +G_DEFINE_BOXED_TYPE(WebKitUserStyleSheet, webkit_user_style_sheet, webkit_user_style_sheet_ref, webkit_user_style_sheet_unref) + +/** + * webkit_user_style_sheet_ref: + * @user_style_sheet: a #WebKitUserStyleSheet + * + * Atomically increments the reference count of @user_style_sheet by one. + * This function is MT-safe and may be called from any thread. + * + * Returns: The passed #WebKitUserStyleSheet + * + * Since: 2.6 + */ +WebKitUserStyleSheet* webkit_user_style_sheet_ref(WebKitUserStyleSheet* userStyleSheet) +{ + g_atomic_int_inc(&userStyleSheet->referenceCount); + return userStyleSheet; +} + +/** + * webkit_user_style_sheet_unref: + * @user_style_sheet: a #WebKitUserStyleSheet + * + * Atomically decrements the reference count of @user_style_sheet by one. + * If the reference count drops to 0, all memory allocated by + * #WebKitUserStyleSheet is released. This function is MT-safe and may be + * called from any thread. + * + * Since: 2.6 + */ +void webkit_user_style_sheet_unref(WebKitUserStyleSheet* userStyleSheet) +{ + if (g_atomic_int_dec_and_test(&userStyleSheet->referenceCount)) { + userStyleSheet->~WebKitUserStyleSheet(); + fastFree(userStyleSheet); + } +} + +/** + * webkit_user_style_sheet_new: + * @source: Source code of the user style sheet. + * @injected_frames: A #WebKitUserContentInjectedFrames value + * @level: A #WebKitUserStyleLevel + * @whitelist: (array zero-terminated=1) (allow-none): A whitelist of URI patterns or %NULL + * @blacklist: (array zero-terminated=1) (allow-none): A blacklist of URI patterns or %NULL + * + * Creates a new user style sheet. Style sheets can be applied to some URIs + * only by passing non-null values for @whitelist or @blacklist. Passing a + * %NULL whitelist implies that all URIs are on the whitelist. The style + * sheet is applied if an URI matches the whitelist and not the blacklist. + * URI patterns must be of the form `[protocol]://[host]/[path]`, where the + * *host* and *path* components can contain the wildcard character (`*`) to + * represent zero or more other characters. + * + * Returns: A new #WebKitUserStyleSheet + * + * Since: 2.6 + */ +WebKitUserStyleSheet* webkit_user_style_sheet_new(const gchar* source, WebKitUserContentInjectedFrames injectedFrames, WebKitUserStyleLevel level, const char* const* whitelist, const char* const* blacklist) +{ + g_return_val_if_fail(source, nullptr); + WebKitUserStyleSheet* userStyleSheet = static_cast<WebKitUserStyleSheet*>(fastMalloc(sizeof(WebKitUserStyleSheet))); + new (userStyleSheet) WebKitUserStyleSheet(source, injectedFrames, level, whitelist, blacklist); + return userStyleSheet; +} + +API::UserStyleSheet& webkitUserStyleSheetGetUserStyleSheet(WebKitUserStyleSheet* userStyleSheet) +{ + return *userStyleSheet->userStyleSheet; +} + +struct _WebKitUserScript { + _WebKitUserScript(const gchar* source, WebKitUserContentInjectedFrames injectedFrames, WebKitUserScriptInjectionTime injectionTime, const gchar* const* whitelist, const gchar* const* blacklist) + : userScript(adoptRef(new API::UserScript(UserScript { + String::fromUTF8(source), URL { }, + toStringVector(whitelist), toStringVector(blacklist), + toUserScriptInjectionTime(injectionTime), + toUserContentInjectedFrames(injectedFrames) }, API::UserContentWorld::normalWorld()))) + , referenceCount(1) + { + } + + RefPtr<API::UserScript> userScript; + int referenceCount; +}; + +G_DEFINE_BOXED_TYPE(WebKitUserScript, webkit_user_script, webkit_user_script_ref, webkit_user_script_unref) + +/** + * webkit_user_script_ref: + * @user_script: a #WebKitUserScript + * + * Atomically increments the reference count of @user_script by one. + * This function is MT-safe and may be called from any thread. + * + * Returns: The passed #WebKitUserScript + * + * Since: 2.6 + */ +WebKitUserScript* webkit_user_script_ref(WebKitUserScript* userScript) +{ + g_atomic_int_inc(&userScript->referenceCount); + return userScript; +} + +/** + * webkit_user_script_unref: + * @user_script: a #WebKitUserScript + * + * Atomically decrements the reference count of @user_script by one. + * If the reference count drops to 0, all memory allocated by + * #WebKitUserScript is released. This function is MT-safe and may be called + * from any thread. + * + * Since: 2.6 + */ +void webkit_user_script_unref(WebKitUserScript* userScript) +{ + if (g_atomic_int_dec_and_test(&userScript->referenceCount)) { + userScript->~WebKitUserScript(); + fastFree(userScript); + } +} + +/** + * webkit_user_script_new: + * @source: Source code of the user script. + * @injected_frames: A #WebKitUserContentInjectedFrames value + * @injection_time: A #WebKitUserScriptInjectionTime value + * @whitelist: (array zero-terminated=1) (allow-none): A whitelist of URI patterns or %NULL + * @blacklist: (array zero-terminated=1) (allow-none): A blacklist of URI patterns or %NULL + * + * Creates a new user script. Scripts can be applied to some URIs + * only by passing non-null values for @whitelist or @blacklist. Passing a + * %NULL whitelist implies that all URIs are on the whitelist. The script + * is applied if an URI matches the whitelist and not the blacklist. + * URI patterns must be of the form `[protocol]://[host]/[path]`, where the + * *host* and *path* components can contain the wildcard character (`*`) to + * represent zero or more other characters. + * + * Returns: A new #WebKitUserScript + * + * Since: 2.6 + */ +WebKitUserScript* webkit_user_script_new(const gchar* source, WebKitUserContentInjectedFrames injectedFrames, WebKitUserScriptInjectionTime injectionTime, const gchar* const* whitelist, const gchar* const* blacklist) +{ + g_return_val_if_fail(source, nullptr); + WebKitUserScript* userScript = static_cast<WebKitUserScript*>(fastMalloc(sizeof(WebKitUserScript))); + new (userScript) WebKitUserScript(source, injectedFrames, injectionTime, whitelist, blacklist); + return userScript; +} + +API::UserScript& webkitUserScriptGetUserScript(WebKitUserScript* userScript) +{ + return *userScript->userScript; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserContent.h b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContent.h new file mode 100644 index 000000000..c3f1ed569 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContent.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitUserContent_h +#define WebKitUserContent_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +/** + * WebKitUserContentInjectedFrames: + * @WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES: Insert the user style + * sheet in all the frames loaded by the web view, including + * nested frames. This is the default. + * @WEBKIT_USER_CONTENT_INJECT_TOP_FRAME: Insert the user style + * sheet *only* in the top-level frame loaded by the web view, + * and *not* in the nested frames. + * + * Specifies in which frames user style sheets are to be inserted in. + * + * Since: 2.6 + */ +typedef enum { + WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, + WEBKIT_USER_CONTENT_INJECT_TOP_FRAME, +} WebKitUserContentInjectedFrames; + +/** + * WebKitUserStyleLevel: + * @WEBKIT_USER_STYLE_LEVEL_USER: The style sheet is an user style sheet, + * its contents always override other style sheets. This is the default. + * @WEBKIT_USER_STYLE_LEVEL_AUTHOR: The style sheet will be treated as if + * it was provided by the loaded documents. That means other user style + * sheets may still override it. + * + * Specifies how to treat an user style sheet. + * + * Since: 2.6 + */ +typedef enum { + WEBKIT_USER_STYLE_LEVEL_USER, + WEBKIT_USER_STYLE_LEVEL_AUTHOR, +} WebKitUserStyleLevel; + +#define WEBKIT_TYPE_USER_STYLE_SHEET (webkit_user_style_sheet_get_type()) + +typedef struct _WebKitUserStyleSheet WebKitUserStyleSheet; + +WEBKIT_API GType +webkit_user_style_sheet_get_type (void); + +WEBKIT_API WebKitUserStyleSheet * +webkit_user_style_sheet_ref (WebKitUserStyleSheet *user_style_sheet); + +WEBKIT_API void +webkit_user_style_sheet_unref (WebKitUserStyleSheet *user_style_sheet); + +WEBKIT_API WebKitUserStyleSheet * +webkit_user_style_sheet_new (const gchar *source, + WebKitUserContentInjectedFrames injected_frames, + WebKitUserStyleLevel level, + const gchar* const *whitelist, + const gchar* const *blacklist); + +/** + * WebKitUserScriptInjectionTime: + * @WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START: Insert the code of the user + * script at the beginning of loaded documents. This is the default. + * @WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END: Insert the code of the user + * script at the end of the loaded documents. + * + * Specifies at which place of documents an user script will be inserted. + * + * Since: 2.6 + */ +typedef enum { + WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START, + WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, +} WebKitUserScriptInjectionTime; + +#define WEBKIT_TYPE_USER_SCRIPT (webkit_user_script_get_type()) + +typedef struct _WebKitUserScript WebKitUserScript; + +WEBKIT_API GType +webkit_user_script_get_type (void); + +WEBKIT_API WebKitUserScript * +webkit_user_script_ref (WebKitUserScript *user_script); + +WEBKIT_API void +webkit_user_script_unref (WebKitUserScript *user_script); + +WEBKIT_API WebKitUserScript * +webkit_user_script_new (const gchar *source, + WebKitUserContentInjectedFrames injected_frames, + WebKitUserScriptInjectionTime injection_time, + const gchar* const *whitelist, + const gchar* const *blacklist); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.cpp new file mode 100644 index 000000000..5c7d7af38 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitUserContentManager.h" + +#include "APISerializedScriptValue.h" +#include "WebKitJavascriptResultPrivate.h" +#include "WebKitPrivate.h" +#include "WebKitUserContentManagerPrivate.h" +#include "WebKitUserContentPrivate.h" +#include "WebKitWebContextPrivate.h" +#include "WebScriptMessageHandler.h" +#include <wtf/glib/GRefPtr.h> + +using namespace WebCore; +using namespace WebKit; + +struct _WebKitUserContentManagerPrivate { + _WebKitUserContentManagerPrivate() + : userContentController(adoptRef(new WebUserContentControllerProxy)) + { + } + + RefPtr<WebUserContentControllerProxy> userContentController; +}; + +/** + * SECTION:WebKitUserContentManager + * @short_description: Manages user-defined content which affects web pages. + * @title: WebKitUserContentManager + * + * Using a #WebKitUserContentManager user CSS style sheets can be set to + * be injected in the web pages loaded by a #WebKitWebView, by + * webkit_user_content_manager_add_style_sheet(). + * + * To use a #WebKitUserContentManager, it must be created using + * webkit_user_content_manager_new(), and then passed to + * webkit_web_view_new_with_user_content_manager(). User style + * sheets can be created with webkit_user_style_sheet_new(). + * + * User style sheets can be added and removed at any time, but + * they will affect the web pages loaded afterwards. + * + * Since: 2.6 + */ + +WEBKIT_DEFINE_TYPE(WebKitUserContentManager, webkit_user_content_manager, G_TYPE_OBJECT) + +enum { + SCRIPT_MESSAGE_RECEIVED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +static void webkit_user_content_manager_class_init(WebKitUserContentManagerClass* klass) +{ + GObjectClass* gObjectClass = G_OBJECT_CLASS(klass); + + /** + * WebKitUserContentManager::script-message-received: + * @manager: the #WebKitUserContentManager + * @js_result: the #WebKitJavascriptResult holding the value received from the JavaScript world. + * + * This signal is emitted when JavaScript in a web view calls + * <code>window.webkit.messageHandlers.<name>.postMessage()</code>, after registering + * <code><name></code> using + * webkit_user_content_manager_register_script_message_handler() + * + * Since: 2.8 + */ + signals[SCRIPT_MESSAGE_RECEIVED] = + g_signal_new( + "script-message-received", + G_TYPE_FROM_CLASS(gObjectClass), + static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED), + 0, nullptr, nullptr, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + WEBKIT_TYPE_JAVASCRIPT_RESULT); +} + +/** + * webkit_user_content_manager_new: + * + * Creates a new user content manager. + * + * Returns: A #WebKitUserContentManager + * + * Since: 2.6 + */ +WebKitUserContentManager* webkit_user_content_manager_new() +{ + return WEBKIT_USER_CONTENT_MANAGER(g_object_new(WEBKIT_TYPE_USER_CONTENT_MANAGER, nullptr)); +} + +/** + * webkit_user_content_manager_add_style_sheet: + * @manager: A #WebKitUserContentManager + * @stylesheet: A #WebKitUserStyleSheet + * + * Adds a #WebKitUserStyleSheet to the given #WebKitUserContentManager. + * The same #WebKitUserStyleSheet can be reused with multiple + * #WebKitUserContentManager instances. + * + * Since: 2.6 + */ +void webkit_user_content_manager_add_style_sheet(WebKitUserContentManager* manager, WebKitUserStyleSheet* styleSheet) +{ + g_return_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(manager)); + g_return_if_fail(styleSheet); + manager->priv->userContentController->addUserStyleSheet(webkitUserStyleSheetGetUserStyleSheet(styleSheet)); +} + +/** + * webkit_user_content_manager_remove_all_style_sheets: + * @manager: A #WebKitUserContentManager + * + * Removes all user style sheets from the given #WebKitUserContentManager. + * + * Since: 2.6 + */ +void webkit_user_content_manager_remove_all_style_sheets(WebKitUserContentManager* manager) +{ + g_return_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(manager)); + manager->priv->userContentController->removeAllUserStyleSheets(); +} + +/** + * webkit_user_content_manager_add_script: + * @manager: A #WebKitUserContentManager + * @script: A #WebKitUserScript + * + * Adds a #WebKitUserScript to the given #WebKitUserContentManager. + * The same #WebKitUserScript can be reused with multiple + * #WebKitUserContentManager instances. + * + * Since: 2.6 + */ +void webkit_user_content_manager_add_script(WebKitUserContentManager* manager, WebKitUserScript* script) +{ + g_return_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(manager)); + g_return_if_fail(script); + manager->priv->userContentController->addUserScript(webkitUserScriptGetUserScript(script)); +} + +/** + * webkit_user_content_manager_remove_all_scripts: + * @manager: A #WebKitUserContentManager + * + * Removes all user scripts from the given #WebKitUserContentManager + * + * Since: 2.6 + */ +void webkit_user_content_manager_remove_all_scripts(WebKitUserContentManager* manager) +{ + g_return_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(manager)); + manager->priv->userContentController->removeAllUserScripts(); +} + +class ScriptMessageClientGtk final : public WebScriptMessageHandler::Client { +public: + ScriptMessageClientGtk(WebKitUserContentManager* manager, const char* handlerName) + : m_handlerName(g_quark_from_string(handlerName)) + , m_manager(manager) + { + } + + void didPostMessage(WebPageProxy& page, const FrameInfoData&, WebCore::SerializedScriptValue& serializedScriptValue) override + { + WebKitJavascriptResult* jsResult = webkitJavascriptResultCreate(WEBKIT_WEB_VIEW(page.viewWidget()), serializedScriptValue); + g_signal_emit(m_manager, signals[SCRIPT_MESSAGE_RECEIVED], m_handlerName, jsResult); + webkit_javascript_result_unref(jsResult); + } + + virtual ~ScriptMessageClientGtk() { } + +private: + GQuark m_handlerName; + WebKitUserContentManager* m_manager; +}; + +/** + * webkit_user_content_manager_register_script_message_handler: + * @manager: A #WebKitUserContentManager + * @name: Name of the script message channel + * + * Registers a new user script message handler. After it is registered, + * scripts can use `window.webkit.messageHandlers.<name>.postMessage(value)` + * to send messages. Those messages are received by connecting handlers + * to the #WebKitUserContentManager::script-message-received signal. The + * handler name is used as the detail of the signal. To avoid race + * conditions between registering the handler name, and starting to + * receive the signals, it is recommended to connect to the signal + * *before* registering the handler name: + * + * <informalexample><programlisting> + * WebKitWebView *view = webkit_web_view_new (); + * WebKitUserContentManager *manager = webkit_web_view_get_user_content_manager (); + * g_signal_connect (manager, "script-message-received::foobar", + * G_CALLBACK (handle_script_message), NULL); + * webkit_user_content_manager_register_script_message_handler (manager, "foobar"); + * </programlisting></informalexample> + * + * Registering a script message handler will fail if the requested + * name has been already registered before. + * + * Returns: %TRUE if message handler was registered successfully, or %FALSE otherwise. + * + * Since: 2.8 + */ +gboolean webkit_user_content_manager_register_script_message_handler(WebKitUserContentManager* manager, const char* name) +{ + g_return_val_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(manager), FALSE); + g_return_val_if_fail(name, FALSE); + + Ref<WebScriptMessageHandler> handler = + WebScriptMessageHandler::create(std::make_unique<ScriptMessageClientGtk>(manager, name), String::fromUTF8(name), API::UserContentWorld::normalWorld()); + return manager->priv->userContentController->addUserScriptMessageHandler(handler.get()); +} + +/** + * webkit_user_content_manager_unregister_script_message_handler: + * @manager: A #WebKitUserContentManager + * @name: Name of the script message channel + * + * Unregisters a previously registered message handler. + * + * Note that this does *not* disconnect handlers for the + * #WebKitUserContentManager::script-message-received signal, + * they will be kept connected, but the signal will not be emitted + * unless the handler name is registered again. + * + * See also webkit_user_content_manager_register_script_message_handler() + * + * Since: 2.8 + */ +void webkit_user_content_manager_unregister_script_message_handler(WebKitUserContentManager* manager, const char* name) +{ + g_return_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(manager)); + g_return_if_fail(name); + manager->priv->userContentController->removeUserMessageHandlerForName(String::fromUTF8(name), API::UserContentWorld::normalWorld()); +} + +WebUserContentControllerProxy* webkitUserContentManagerGetUserContentControllerProxy(WebKitUserContentManager* manager) +{ + return manager->priv->userContentController.get(); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.h b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.h new file mode 100644 index 000000000..86d24a113 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitUserContentManager_h +#define WebKitUserContentManager_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitUserContent.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_USER_CONTENT_MANAGER (webkit_user_content_manager_get_type()) +#define WEBKIT_USER_CONTENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_USER_CONTENT_MANAGER, WebKitUserContentManager)) +#define WEBKIT_IS_USER_CONTENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_USER_CONTENT_MANAGER)) +#define WEBKIT_USER_CONTENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_USER_CONTENT_MANAGER, WebKitUserContentManagerClass)) +#define WEBKIT_IS_USER_CONTENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_USER_CONTENT_MANAGER)) +#define WEBKIT_USER_CONTENT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_USER_CONTENT_MANAGER, WebKitUserContentManagerClass)) + +typedef struct _WebKitUserContentManager WebKitUserContentManager; +typedef struct _WebKitUserContentManagerClass WebKitUserContentManagerClass; +typedef struct _WebKitUserContentManagerPrivate WebKitUserContentManagerPrivate; + + +struct _WebKitUserContentManager { + GObject parent; + + /*< private >*/ + WebKitUserContentManagerPrivate *priv; +}; + +struct _WebKitUserContentManagerClass { + GObjectClass parent_class; + + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); +}; + + +WEBKIT_API GType +webkit_user_content_manager_get_type (void); + +WEBKIT_API WebKitUserContentManager * +webkit_user_content_manager_new (void); + +WEBKIT_API void +webkit_user_content_manager_add_style_sheet (WebKitUserContentManager *manager, + WebKitUserStyleSheet *stylesheet); +WEBKIT_API void +webkit_user_content_manager_remove_all_style_sheets (WebKitUserContentManager *manager); + +WEBKIT_API gboolean +webkit_user_content_manager_register_script_message_handler (WebKitUserContentManager *manager, + const gchar *name); +WEBKIT_API void +webkit_user_content_manager_unregister_script_message_handler (WebKitUserContentManager *manager, + const gchar *name); + +WEBKIT_API void +webkit_user_content_manager_add_script (WebKitUserContentManager *manager, + WebKitUserScript *script); + +WEBKIT_API void +webkit_user_content_manager_remove_all_scripts (WebKitUserContentManager *manager); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManagerPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManagerPrivate.h new file mode 100644 index 000000000..f791a5357 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManagerPrivate.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitUserContentManagerPrivate_h +#define WebKitUserContentManagerPrivate_h + +#include "WebKitUserContentManager.h" +#include "WebUserContentControllerProxy.h" + +WebKit::WebUserContentControllerProxy* webkitUserContentManagerGetUserContentControllerProxy(WebKitUserContentManager*); + +#endif // WebKitUserContentManagerPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentPrivate.h new file mode 100644 index 000000000..444e2caaa --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentPrivate.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitUserContentPrivate_h +#define WebKitUserContentPrivate_h + +#include "APIUserScript.h" +#include "APIUserStyleSheet.h" +#include "WebKitUserContent.h" +#include <WebCore/UserScript.h> +#include <WebCore/UserStyleSheet.h> + +API::UserScript& webkitUserScriptGetUserScript(WebKitUserScript*); +API::UserStyleSheet& webkitUserStyleSheetGetUserStyleSheet(WebKitUserStyleSheet*); + +#endif // WebKitUserContentPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.cpp new file mode 100644 index 000000000..1220a9e6d --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2014 Igalia S.L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "WebKitUserMediaPermissionRequest.h" + +#include "UserMediaPermissionRequestProxy.h" +#include "WebKitPermissionRequest.h" +#include "WebKitUserMediaPermissionRequestPrivate.h" +#include <glib/gi18n-lib.h> + +using namespace WebKit; + +/** + * SECTION: WebKitUserMediaPermissionRequest + * @Short_description: A permission request for accessing user's audio/video devices. + * @Title: WebKitUserMediaPermissionRequest + * @See_also: #WebKitPermissionRequest, #WebKitWebView + * + * WebKitUserMediaPermissionRequest represents a request for + * permission to decide whether WebKit should be allowed to access the user's + * audio and video source devices when requested throught the getUserMedia API. + * + * When a WebKitUserMediaPermissionRequest is not handled by the user, + * it is denied by default. + * + * Since: 2.8 + */ + +enum { + PROP_0, + PROP_IS_FOR_AUDIO_DEVICE, + PROP_IS_FOR_VIDEO_DEVICE +}; + +static void webkit_permission_request_interface_init(WebKitPermissionRequestIface*); + +struct _WebKitUserMediaPermissionRequestPrivate { + RefPtr<UserMediaPermissionRequestProxy> request; + bool madeDecision; +}; + +WEBKIT_DEFINE_TYPE_WITH_CODE( + WebKitUserMediaPermissionRequest, webkit_user_media_permission_request, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(WEBKIT_TYPE_PERMISSION_REQUEST, webkit_permission_request_interface_init)) + +static void webkitUserMediaPermissionRequestAllow(WebKitPermissionRequest* request) +{ + ASSERT(WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST(request)); + + WebKitUserMediaPermissionRequestPrivate* priv = WEBKIT_USER_MEDIA_PERMISSION_REQUEST(request)->priv; + + // Only one decision at a time. + if (priv->madeDecision) + return; + + priv->madeDecision = true; + + auto videoDeviceUIDs = priv->request->videoDeviceUIDs(); + auto audioDeviceUIDs = priv->request->audioDeviceUIDs(); + + auto videoDevice = !videoDeviceUIDs.isEmpty() ? videoDeviceUIDs[0] : emptyString(); + auto audioDevice = !audioDeviceUIDs.isEmpty() ? audioDeviceUIDs[0] : emptyString(); + + priv->request->allow(audioDevice, videoDevice); +} + +static void webkitUserMediaPermissionRequestDeny(WebKitPermissionRequest* request) +{ + ASSERT(WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST(request)); + + WebKitUserMediaPermissionRequestPrivate* priv = WEBKIT_USER_MEDIA_PERMISSION_REQUEST(request)->priv; + + // Only one decision at a time. + if (priv->madeDecision) + return; + + priv->madeDecision = true; + priv->request->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied); +} + +static void webkit_permission_request_interface_init(WebKitPermissionRequestIface* iface) +{ + iface->allow = webkitUserMediaPermissionRequestAllow; + iface->deny = webkitUserMediaPermissionRequestDeny; +} + +static void webkitUserMediaPermissionRequestDispose(GObject* object) +{ + // Default behaviour when no decision has been made is denying the request. + webkitUserMediaPermissionRequestDeny(WEBKIT_PERMISSION_REQUEST(object)); + G_OBJECT_CLASS(webkit_user_media_permission_request_parent_class)->dispose(object); +} + +/** + * webkit_user_media_permission_is_for_audio_device: + * @request: a #WebKitUserMediaPermissionRequest + * + * Returns: %TRUE if access to an audio device was requested. + * + * Since: 2.8 + */ +gboolean webkit_user_media_permission_is_for_audio_device(WebKitUserMediaPermissionRequest* request) +{ + g_return_val_if_fail(request->priv->request, FALSE); + return request->priv->request->requiresAudio(); +} + +/** + * webkit_user_media_permission_is_for_video_device: + * @request: a #WebKitUserMediaPermissionRequest + * + * Returns: %TRUE if access to a video device was requested. + * + * Since: 2.8 + */ +gboolean webkit_user_media_permission_is_for_video_device(WebKitUserMediaPermissionRequest* request) +{ + g_return_val_if_fail(request->priv->request, FALSE); + return request->priv->request->requiresVideo(); +} + +static void webkitUserMediaPermissionRequestGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) +{ + WebKitUserMediaPermissionRequest* request = WEBKIT_USER_MEDIA_PERMISSION_REQUEST(object); + + switch (propId) { + case PROP_IS_FOR_AUDIO_DEVICE: + g_value_set_boolean(value, webkit_user_media_permission_is_for_audio_device(request)); + break; + case PROP_IS_FOR_VIDEO_DEVICE: + g_value_set_boolean(value, webkit_user_media_permission_is_for_video_device(request)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkit_user_media_permission_request_class_init(WebKitUserMediaPermissionRequestClass* klass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(klass); + objectClass->dispose = webkitUserMediaPermissionRequestDispose; + objectClass->get_property = webkitUserMediaPermissionRequestGetProperty; + + /** + * WebKitUserPermissionRequest:is-for-audio-device: + * + * Whether the media device to which the permission was requested has a microphone or not. + * + * Since: 2.8 + */ + g_object_class_install_property(objectClass, PROP_IS_FOR_AUDIO_DEVICE, + g_param_spec_boolean("is-for-audio-device", _("Is for audio device"), + _("Whether the media device to which the permission was requested has a microphone or not."), + FALSE, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitUserPermissionRequest:is-for-video-device: + * + * Whether the media device to which the permission was requested has a video capture capability or not. + * + * Since: 2.8 + */ + g_object_class_install_property(objectClass, PROP_IS_FOR_VIDEO_DEVICE, + g_param_spec_boolean("is-for-video-device", _("Is for video device"), + _("Whether the media device to which the permission was requested has a video capture capability or not."), + FALSE, + WEBKIT_PARAM_READABLE)); +} + +WebKitUserMediaPermissionRequest* webkitUserMediaPermissionRequestCreate(UserMediaPermissionRequestProxy& request, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin) +{ + WebKitUserMediaPermissionRequest* usermediaPermissionRequest = WEBKIT_USER_MEDIA_PERMISSION_REQUEST(g_object_new(WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST, nullptr)); + + // FIXME: store SecurityOrigins + UNUSED_PARAM(userMediaDocumentOrigin); + UNUSED_PARAM(topLevelDocumentOrigin); + + usermediaPermissionRequest->priv->request = &request; + return usermediaPermissionRequest; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.h b/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.h new file mode 100644 index 000000000..ad382b1ba --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014 Igalia S.L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitUserMediaPermissionRequest_h +#define WebKitUserMediaPermissionRequest_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST (webkit_user_media_permission_request_get_type()) +#define WEBKIT_USER_MEDIA_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST, WebKitUserMediaPermissionRequest)) +#define WEBKIT_USER_MEDIA_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST, WebKitUserMediaPermissionRequestClass)) +#define WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST)) +#define WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST)) +#define WEBKIT_USER_MEDIA_PERMISSION_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST, WebKitUserMediaPermissionRequestClass)) + +typedef struct _WebKitUserMediaPermissionRequest WebKitUserMediaPermissionRequest; +typedef struct _WebKitUserMediaPermissionRequestClass WebKitUserMediaPermissionRequestClass; +typedef struct _WebKitUserMediaPermissionRequestPrivate WebKitUserMediaPermissionRequestPrivate; + +struct _WebKitUserMediaPermissionRequest { + GObject parent; + + /*< private >*/ + WebKitUserMediaPermissionRequestPrivate *priv; +}; + +struct _WebKitUserMediaPermissionRequestClass { + GObjectClass parent_class; + + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); +}; + +WEBKIT_API GType +webkit_user_media_permission_request_get_type (void); + +WEBKIT_API gboolean +webkit_user_media_permission_is_for_audio_device (WebKitUserMediaPermissionRequest *request); + +WEBKIT_API gboolean +webkit_user_media_permission_is_for_video_device (WebKitUserMediaPermissionRequest *request); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequestPrivate.h new file mode 100644 index 000000000..328a1616e --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequestPrivate.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2014 Igalia S.L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef WebKitUserMediaPermissionRequestPrivate_h +#define WebKitUserMediaPermissionRequestPrivate_h + +#include "WebKitPrivate.h" +#include "WebKitUserMediaPermissionRequest.h" + +class SecurityOrigin; + +WebKitUserMediaPermissionRequest* webkitUserMediaPermissionRequestCreate(WebKit::UserMediaPermissionRequestProxy&, API::SecurityOrigin&, API::SecurityOrigin&); + +#endif // WebKitUserMediaPermissionRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitVersion.h.in b/Source/WebKit2/UIProcess/API/gtk/WebKitVersion.h.in index b1c5af45d..1364bf602 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitVersion.h.in +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitVersion.h.in @@ -35,7 +35,7 @@ G_BEGIN_DECLS * application compile time, rather than from the library linked * against at application run time. */ -#define WEBKIT_MAJOR_VERSION (@WEBKIT_MAJOR_VERSION@) +#define WEBKIT_MAJOR_VERSION (@PROJECT_VERSION_MAJOR@) /** * WEBKIT_MINOR_VERSION: @@ -44,7 +44,7 @@ G_BEGIN_DECLS * application compile time, rather than from the library linked * against at application run time. */ -#define WEBKIT_MINOR_VERSION (@WEBKIT_MINOR_VERSION@) +#define WEBKIT_MINOR_VERSION (@PROJECT_VERSION_MINOR@) /** * WEBKIT_MICRO_VERSION: @@ -53,7 +53,7 @@ G_BEGIN_DECLS * application compile time, rather than from the library linked * against at application run time. */ -#define WEBKIT_MICRO_VERSION (@WEBKIT_MICRO_VERSION@) +#define WEBKIT_MICRO_VERSION (@PROJECT_VERSION_MICRO@) /** * WEBKIT_CHECK_VERSION: diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp index 1528324ba..e80255f4a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp @@ -20,39 +20,48 @@ #include "config.h" #include "WebKitWebContext.h" +#include "APICustomProtocolManagerClient.h" +#include "APIDownloadClient.h" +#include "APIPageConfiguration.h" +#include "APIProcessPoolConfiguration.h" #include "APIString.h" -#include "WebBatteryManagerProxy.h" +#include "TextChecker.h" +#include "TextCheckerState.h" #include "WebCertificateInfo.h" -#include "WebCookieManagerProxy.h" #include "WebGeolocationManagerProxy.h" -#include "WebKitBatteryProvider.h" -#include "WebKitCertificateInfoPrivate.h" -#include "WebKitCookieManagerPrivate.h" +#include "WebKitCustomProtocolManagerClient.h" #include "WebKitDownloadClient.h" #include "WebKitDownloadPrivate.h" #include "WebKitFaviconDatabasePrivate.h" #include "WebKitGeolocationProvider.h" #include "WebKitInjectedBundleClient.h" +#include "WebKitNetworkProxySettingsPrivate.h" +#include "WebKitNotificationProvider.h" #include "WebKitPluginPrivate.h" #include "WebKitPrivate.h" -#include "WebKitRequestManagerClient.h" #include "WebKitSecurityManagerPrivate.h" -#include "WebKitTextChecker.h" +#include "WebKitSecurityOriginPrivate.h" +#include "WebKitSettingsPrivate.h" #include "WebKitURISchemeRequestPrivate.h" +#include "WebKitUserContentManagerPrivate.h" #include "WebKitWebContextPrivate.h" #include "WebKitWebViewBasePrivate.h" -#include "WebKitWebViewGroupPrivate.h" -#include "WebResourceCacheManagerProxy.h" +#include "WebKitWebViewPrivate.h" +#include "WebKitWebsiteDataManagerPrivate.h" +#include "WebNotificationManagerProxy.h" +#include "WebsiteDataType.h" #include <WebCore/FileSystem.h> #include <WebCore/IconDatabase.h> #include <WebCore/Language.h> +#include <glib/gi18n-lib.h> #include <libintl.h> +#include <memory> #include <wtf/HashMap.h> -#include <wtf/OwnPtr.h> +#include <wtf/NeverDestroyed.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -68,11 +77,9 @@ using namespace WebKit; * You can define the #WebKitCacheModel and #WebKitProcessModel with * webkit_web_context_set_cache_model() and * webkit_web_context_set_process_model(), depending on the needs of - * your application. You can access the #WebKitCookieManager or the - * #WebKitSecurityManager to specify the behaviour of your application - * regarding cookies and security, using - * webkit_web_context_get_cookie_manager() and - * webkit_web_context_get_security_manager() for that. + * your application. You can access the #WebKitSecurityManager to specify + * the behaviour of your application regarding security using + * webkit_web_context_get_security_manager(). * * It is also possible to change your preferred language or enable * spell checking, using webkit_web_context_set_preferred_languages(), @@ -82,23 +89,32 @@ using namespace WebKit; * You can use webkit_web_context_register_uri_scheme() to register * custom URI schemes, and manage several other settings. * + * TLS certificate validation failure is now treated as a transport + * error by default. To handle TLS failures differently, you can + * connect to #WebKitWebView::load-failed-with-tls-errors. + * Alternatively, you can use webkit_web_context_set_tls_errors_policy() + * to set the policy %WEBKIT_TLS_ERRORS_POLICY_IGNORE; however, this is + * not appropriate for Internet applications. + * */ enum { + PROP_0, + + PROP_LOCAL_STORAGE_DIRECTORY, + PROP_WEBSITE_DATA_MANAGER +}; + +enum { DOWNLOAD_STARTED, INITIALIZE_WEB_EXTENSIONS, + INITIALIZE_NOTIFICATION_PERMISSIONS, LAST_SIGNAL }; class WebKitURISchemeHandler: public RefCounted<WebKitURISchemeHandler> { public: - WebKitURISchemeHandler() - : m_callback(0) - , m_userData(0) - , m_destroyNotify(0) - { - } WebKitURISchemeHandler(WebKitURISchemeRequestCallback callback, void* userData, GDestroyNotify destroyNotify) : m_callback(callback) , m_userData(userData) @@ -125,50 +141,221 @@ public: } private: - WebKitURISchemeRequestCallback m_callback; - void* m_userData; - GDestroyNotify m_destroyNotify; + WebKitURISchemeRequestCallback m_callback { nullptr }; + void* m_userData { nullptr }; + GDestroyNotify m_destroyNotify { nullptr }; }; typedef HashMap<String, RefPtr<WebKitURISchemeHandler> > URISchemeHandlerMap; typedef HashMap<uint64_t, GRefPtr<WebKitURISchemeRequest> > URISchemeRequestMap; struct _WebKitWebContextPrivate { - RefPtr<WebContext> context; + RefPtr<WebProcessPool> processPool; + bool clientsDetached; - GRefPtr<WebKitCookieManager> cookieManager; GRefPtr<WebKitFaviconDatabase> faviconDatabase; GRefPtr<WebKitSecurityManager> securityManager; - RefPtr<WebSoupCustomProtocolRequestManager> requestManager; URISchemeHandlerMap uriSchemeHandlers; URISchemeRequestMap uriSchemeRequests; #if ENABLE(GEOLOCATION) RefPtr<WebKitGeolocationProvider> geolocationProvider; #endif -#if ENABLE(BATTERY_STATUS) - RefPtr<WebKitBatteryProvider> batteryProvider; -#endif -#if ENABLE(SPELLCHECK) - OwnPtr<WebKitTextChecker> textChecker; +#if ENABLE(NOTIFICATIONS) + RefPtr<WebKitNotificationProvider> notificationProvider; #endif + GRefPtr<WebKitWebsiteDataManager> websiteDataManager; + CString faviconDatabaseDirectory; WebKitTLSErrorsPolicy tlsErrorsPolicy; + WebKitProcessModel processModel; + unsigned processCountLimit; HashMap<uint64_t, WebKitWebView*> webViews; - GRefPtr<WebKitWebViewGroup> defaultWebViewGroup; + unsigned ephemeralPageCount; CString webExtensionsDirectory; GRefPtr<GVariant> webExtensionsInitializationUserData; + + CString localStorageDirectory; }; static guint signals[LAST_SIGNAL] = { 0, }; WEBKIT_DEFINE_TYPE(WebKitWebContext, webkit_web_context, G_TYPE_OBJECT) +static const char* injectedBundleDirectory() +{ +#if ENABLE(DEVELOPER_MODE) + const char* bundleDirectory = g_getenv("WEBKIT_INJECTED_BUNDLE_PATH"); + if (bundleDirectory && g_file_test(bundleDirectory, G_FILE_TEST_IS_DIR)) + return bundleDirectory; +#endif + + static const char* injectedBundlePath = LIBDIR G_DIR_SEPARATOR_S "webkit2gtk-" WEBKITGTK_API_VERSION_STRING + G_DIR_SEPARATOR_S "injected-bundle" G_DIR_SEPARATOR_S; + return injectedBundlePath; +} + +static void webkitWebContextGetProperty(GObject* object, guint propID, GValue* value, GParamSpec* paramSpec) +{ + WebKitWebContext* context = WEBKIT_WEB_CONTEXT(object); + + switch (propID) { + case PROP_LOCAL_STORAGE_DIRECTORY: + g_value_set_string(value, context->priv->localStorageDirectory.data()); + break; + case PROP_WEBSITE_DATA_MANAGER: + g_value_set_object(value, webkit_web_context_get_website_data_manager(context)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec); + } +} + +static void webkitWebContextSetProperty(GObject* object, guint propID, const GValue* value, GParamSpec* paramSpec) +{ + WebKitWebContext* context = WEBKIT_WEB_CONTEXT(object); + + switch (propID) { + case PROP_LOCAL_STORAGE_DIRECTORY: + context->priv->localStorageDirectory = g_value_get_string(value); + break; + case PROP_WEBSITE_DATA_MANAGER: { + gpointer manager = g_value_get_object(value); + context->priv->websiteDataManager = manager ? WEBKIT_WEBSITE_DATA_MANAGER(manager) : nullptr; + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec); + } +} + +static inline WebsiteDataStore::Configuration websiteDataStoreConfigurationForWebProcessPoolConfiguration(const API::ProcessPoolConfiguration& processPoolconfigurarion) +{ + WebsiteDataStore::Configuration configuration; + configuration.applicationCacheDirectory = processPoolconfigurarion.applicationCacheDirectory(); + configuration.networkCacheDirectory = processPoolconfigurarion.diskCacheDirectory(); + configuration.webSQLDatabaseDirectory = processPoolconfigurarion.webSQLDatabaseDirectory(); + configuration.localStorageDirectory = processPoolconfigurarion.localStorageDirectory(); + configuration.mediaKeysStorageDirectory = processPoolconfigurarion.mediaKeysStorageDirectory(); + return configuration; +} + +static void webkitWebContextConstructed(GObject* object) +{ + G_OBJECT_CLASS(webkit_web_context_parent_class)->constructed(object); + + GUniquePtr<char> bundleFilename(g_build_filename(injectedBundleDirectory(), "libwebkit2gtkinjectedbundle.so", nullptr)); + + API::ProcessPoolConfiguration configuration; + configuration.setInjectedBundlePath(WebCore::stringFromFileSystemRepresentation(bundleFilename.get())); + configuration.setMaximumProcessCount(1); + configuration.setDiskCacheSpeculativeValidationEnabled(true); + + WebKitWebContext* webContext = WEBKIT_WEB_CONTEXT(object); + WebKitWebContextPrivate* priv = webContext->priv; + if (priv->websiteDataManager && !webkit_website_data_manager_is_ephemeral(priv->websiteDataManager.get())) { + configuration.setLocalStorageDirectory(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_local_storage_directory(priv->websiteDataManager.get()))); + configuration.setDiskCacheDirectory(WebCore::pathByAppendingComponent(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_disk_cache_directory(priv->websiteDataManager.get())), networkCacheSubdirectory)); + configuration.setApplicationCacheDirectory(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_offline_application_cache_directory(priv->websiteDataManager.get()))); + configuration.setIndexedDBDatabaseDirectory(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_indexeddb_directory(priv->websiteDataManager.get()))); + configuration.setWebSQLDatabaseDirectory(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_websql_directory(priv->websiteDataManager.get()))); + } else if (!priv->localStorageDirectory.isNull()) + configuration.setLocalStorageDirectory(WebCore::stringFromFileSystemRepresentation(priv->localStorageDirectory.data())); + + priv->processPool = WebProcessPool::create(configuration); + + if (!priv->websiteDataManager) + priv->websiteDataManager = adoptGRef(webkitWebsiteDataManagerCreate(websiteDataStoreConfigurationForWebProcessPoolConfiguration(configuration))); + + webkitWebsiteDataManagerAddProcessPool(priv->websiteDataManager.get(), *priv->processPool); + + priv->tlsErrorsPolicy = WEBKIT_TLS_ERRORS_POLICY_FAIL; + priv->processPool->setIgnoreTLSErrors(false); + +#if ENABLE(MEMORY_SAMPLER) + if (getenv("WEBKIT_SAMPLE_MEMORY")) + priv->processPool->startMemorySampler(0); +#endif + + attachInjectedBundleClientToContext(webContext); + attachDownloadClientToContext(webContext); + attachCustomProtocolManagerClientToContext(webContext); + +#if ENABLE(GEOLOCATION) + priv->geolocationProvider = WebKitGeolocationProvider::create(priv->processPool->supplement<WebGeolocationManagerProxy>()); +#endif +#if ENABLE(NOTIFICATIONS) + priv->notificationProvider = WebKitNotificationProvider::create(priv->processPool->supplement<WebNotificationManagerProxy>(), webContext); +#endif +} + +static void webkitWebContextDispose(GObject* object) +{ + WebKitWebContextPrivate* priv = WEBKIT_WEB_CONTEXT(object)->priv; + if (!priv->clientsDetached) { + priv->clientsDetached = true; + priv->processPool->initializeInjectedBundleClient(nullptr); + priv->processPool->setDownloadClient(nullptr); + priv->processPool->setCustomProtocolManagerClient(nullptr); + } + + if (priv->websiteDataManager) { + webkitWebsiteDataManagerRemoveProcessPool(priv->websiteDataManager.get(), *priv->processPool); + priv->websiteDataManager = nullptr; + } + + G_OBJECT_CLASS(webkit_web_context_parent_class)->dispose(object); +} + static void webkit_web_context_class_init(WebKitWebContextClass* webContextClass) { GObjectClass* gObjectClass = G_OBJECT_CLASS(webContextClass); + bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR); + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + + gObjectClass->get_property = webkitWebContextGetProperty; + gObjectClass->set_property = webkitWebContextSetProperty; + gObjectClass->constructed = webkitWebContextConstructed; + gObjectClass->dispose = webkitWebContextDispose; + + /** + * WebKitWebContext:local-storage-directory: + * + * The directory where local storage data will be saved. + * + * Since: 2.8 + * + * Deprecated: 2.10. Use #WebKitWebsiteDataManager:local-storage-directory instead. + */ + g_object_class_install_property( + gObjectClass, + PROP_LOCAL_STORAGE_DIRECTORY, + g_param_spec_string( + "local-storage-directory", + _("Local Storage Directory"), + _("The directory where local storage data will be saved"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebContext:website-data-manager: + * + * The #WebKitWebsiteDataManager associated with this context. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_WEBSITE_DATA_MANAGER, + g_param_spec_object( + "website-data-manager", + _("Website Data Manager"), + _("The WebKitWebsiteDataManager associated with this context"), + WEBKIT_TYPE_WEBSITE_DATA_MANAGER, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + /** * WebKitWebContext::download-started: * @context: the #WebKitWebContext @@ -178,12 +365,13 @@ static void webkit_web_context_class_init(WebKitWebContextClass* webContextClass */ signals[DOWNLOAD_STARTED] = g_signal_new("download-started", - G_TYPE_FROM_CLASS(gObjectClass), - G_SIGNAL_RUN_LAST, - 0, 0, 0, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - WEBKIT_TYPE_DOWNLOAD); + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitWebContextClass, download_started), + nullptr, nullptr, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + WEBKIT_TYPE_DOWNLOAD); /** * WebKitWebContext::initialize-web-extensions: @@ -200,68 +388,138 @@ static void webkit_web_context_class_init(WebKitWebContextClass* webContextClass g_signal_new("initialize-web-extensions", G_TYPE_FROM_CLASS(gObjectClass), G_SIGNAL_RUN_LAST, - 0, nullptr, nullptr, + G_STRUCT_OFFSET(WebKitWebContextClass, initialize_web_extensions), + nullptr, nullptr, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * WebKitWebContext::initialize-notification-permissions: + * @context: the #WebKitWebContext + * + * This signal is emitted when a #WebKitWebContext needs to set + * initial notification permissions for a web process. It is emitted + * when a new web process is about to be launched, and signals the + * most appropriate moment to use + * webkit_web_context_initialize_notification_permissions(). If no + * notification permissions have changed since the last time this + * signal was emitted, then there is no need to call + * webkit_web_context_initialize_notification_permissions() again. + * + * Since: 2.16 + */ + signals[INITIALIZE_NOTIFICATION_PERMISSIONS] = + g_signal_new("initialize-notification-permissions", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitWebContextClass, initialize_notification_permissions), + nullptr, nullptr, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } -static CString injectedBundleDirectory() +static gpointer createDefaultWebContext(gpointer) { - const char* bundleDirectory = g_getenv("WEBKIT_INJECTED_BUNDLE_PATH"); - if (bundleDirectory && g_file_test(bundleDirectory, G_FILE_TEST_IS_DIR)) - return bundleDirectory; + static GRefPtr<WebKitWebContext> webContext = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, nullptr))); + return webContext.get(); +} - static const char* injectedBundlePath = LIBDIR G_DIR_SEPARATOR_S "webkit2gtk-" WEBKITGTK_API_VERSION_STRING - G_DIR_SEPARATOR_S "injected-bundle" G_DIR_SEPARATOR_S; - return injectedBundlePath; +/** + * webkit_web_context_get_default: + * + * Gets the default web context + * + * Returns: (transfer none): a #WebKitWebContext + */ +WebKitWebContext* webkit_web_context_get_default(void) +{ + static GOnce onceInit = G_ONCE_INIT; + return WEBKIT_WEB_CONTEXT(g_once(&onceInit, createDefaultWebContext, 0)); } -static CString injectedBundleFilename() +/** + * webkit_web_context_new: + * + * Create a new #WebKitWebContext + * + * Returns: (transfer full): a newly created #WebKitWebContext + * + * Since: 2.8 + */ +WebKitWebContext* webkit_web_context_new(void) { - GUniquePtr<char> bundleFilename(g_build_filename(injectedBundleDirectory().data(), "libwebkit2gtkinjectedbundle.so", NULL)); - return bundleFilename.get(); + return WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, nullptr)); } -static gpointer createDefaultWebContext(gpointer) +/** + * webkit_web_context_new_ephemeral: + * + * Create a new ephemeral #WebKitWebContext. An ephemeral #WebKitWebContext is a context + * created with an ephemeral #WebKitWebsiteDataManager. This is just a convenient method + * to create ephemeral contexts without having to create your own #WebKitWebsiteDataManager. + * All #WebKitWebView<!-- -->s associated with this context will also be ephemeral. Websites will + * not store any data in the client storage. + * This is normally used to implement private instances. + * + * Returns: (transfer full): a new ephemeral #WebKitWebContext. + * + * Since: 2.16 + */ +WebKitWebContext* webkit_web_context_new_ephemeral() { - bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); - bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + GRefPtr<WebKitWebsiteDataManager> manager = adoptGRef(webkit_website_data_manager_new_ephemeral()); + return WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", manager.get(), nullptr)); +} - static GRefPtr<WebKitWebContext> webContext = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, NULL))); - WebKitWebContextPrivate* priv = webContext->priv; +/** + * webkit_web_context_new_with_website_data_manager: + * @manager: a #WebKitWebsiteDataManager + * + * Create a new #WebKitWebContext with a #WebKitWebsiteDataManager. + * + * Returns: (transfer full): a newly created #WebKitWebContext + * + * Since: 2.10 + */ +WebKitWebContext* webkit_web_context_new_with_website_data_manager(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); - priv->context = WebContext::create(WebCore::filenameToString(injectedBundleFilename().data())); - priv->requestManager = webContext->priv->context->supplement<WebSoupCustomProtocolRequestManager>(); - priv->context->setCacheModel(CacheModelPrimaryWebBrowser); - priv->tlsErrorsPolicy = WEBKIT_TLS_ERRORS_POLICY_IGNORE; + return WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", manager, nullptr)); +} - attachInjectedBundleClientToContext(webContext.get()); - attachDownloadClientToContext(webContext.get()); - attachRequestManagerClientToContext(webContext.get()); +/** + * webkit_web_context_get_website_data_manager: + * @context: the #WebKitWebContext + * + * Get the #WebKitWebsiteDataManager of @context. + * + * Returns: (transfer none): a #WebKitWebsiteDataManager + * + * Since: 2.10 + */ +WebKitWebsiteDataManager* webkit_web_context_get_website_data_manager(WebKitWebContext* context) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr); -#if ENABLE(GEOLOCATION) - priv->geolocationProvider = WebKitGeolocationProvider::create(priv->context->supplement<WebGeolocationManagerProxy>()); -#endif -#if ENABLE(BATTERY_STATUS) - priv->batteryProvider = WebKitBatteryProvider::create(priv->context->supplement<WebBatteryManagerProxy>()); -#endif -#if ENABLE(SPELLCHECK) - priv->textChecker = WebKitTextChecker::create(); -#endif - return webContext.get(); + return context->priv->websiteDataManager.get(); } /** - * webkit_web_context_get_default: + * webkit_web_context_is_ephemeral: + * @context: the #WebKitWebContext * - * Gets the default web context + * Get whether a #WebKitWebContext is ephemeral. * - * Returns: (transfer none): a #WebKitWebContext + * Returns: %TRUE if @context is ephemeral or %FALSE otherwise. + * + * Since: 2.16 */ -WebKitWebContext* webkit_web_context_get_default(void) +gboolean webkit_web_context_is_ephemeral(WebKitWebContext* context) { - static GOnce onceInit = G_ONCE_INIT; - return WEBKIT_WEB_CONTEXT(g_once(&onceInit, createDefaultWebContext, 0)); + g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), FALSE); + + return webkit_website_data_manager_is_ephemeral(context->priv->websiteDataManager.get()); } /** @@ -308,8 +566,8 @@ void webkit_web_context_set_cache_model(WebKitWebContext* context, WebKitCacheMo g_assert_not_reached(); } - if (cacheModel != context->priv->context->cacheModel()) - context->priv->context->setCacheModel(cacheModel); + if (cacheModel != context->priv->processPool->cacheModel()) + context->priv->processPool->setCacheModel(cacheModel); } /** @@ -326,7 +584,7 @@ WebKitCacheModel webkit_web_context_get_cache_model(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), WEBKIT_CACHE_MODEL_WEB_BROWSER); - switch (context->priv->context->cacheModel()) { + switch (context->priv->processPool->cacheModel()) { case CacheModelDocumentViewer: return WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER; case CacheModelPrimaryWebBrowser: @@ -351,14 +609,59 @@ void webkit_web_context_clear_cache(WebKitWebContext* context) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); - context->priv->context->supplement<WebResourceCacheManagerProxy>()->clearCacheForAllOrigins(AllResourceCaches); + OptionSet<WebsiteDataType> websiteDataTypes; + websiteDataTypes |= WebsiteDataType::MemoryCache; + websiteDataTypes |= WebsiteDataType::DiskCache; + auto& websiteDataStore = webkitWebsiteDataManagerGetDataStore(context->priv->websiteDataManager.get()).websiteDataStore(); + websiteDataStore.removeData(websiteDataTypes, std::chrono::system_clock::time_point::min(), [] { }); +} + +/** + * webkit_web_context_set_network_proxy_settings: + * @context: a #WebKitWebContext + * @proxy_mode: a #WebKitNetworkProxyMode + * @proxy_settings: (allow-none): a #WebKitNetworkProxySettings, or %NULL + * + * Set the network proxy settings to be used by connections started in @context. + * By default %WEBKIT_NETWORK_PROXY_MODE_DEFAULT is used, which means that the + * system settings will be used (g_proxy_resolver_get_default()). + * If you want to override the system default settings, you can either use + * %WEBKIT_NETWORK_PROXY_MODE_NO_PROXY to make sure no proxies are used at all, + * or %WEBKIT_NETWORK_PROXY_MODE_CUSTOM to provide your own proxy settings. + * When @proxy_mode is %WEBKIT_NETWORK_PROXY_MODE_CUSTOM @proxy_settings must be + * a valid #WebKitNetworkProxySettings; otherwise, @proxy_settings must be %NULL. + * + * Since: 2.16 + */ +void webkit_web_context_set_network_proxy_settings(WebKitWebContext* context, WebKitNetworkProxyMode proxyMode, WebKitNetworkProxySettings* proxySettings) +{ + g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); + g_return_if_fail((proxyMode != WEBKIT_NETWORK_PROXY_MODE_CUSTOM && !proxySettings) || (proxyMode == WEBKIT_NETWORK_PROXY_MODE_CUSTOM && proxySettings)); + + WebKitWebContextPrivate* priv = context->priv; + switch (proxyMode) { + case WEBKIT_NETWORK_PROXY_MODE_DEFAULT: + priv->processPool->setNetworkProxySettings({ }); + break; + case WEBKIT_NETWORK_PROXY_MODE_NO_PROXY: + priv->processPool->setNetworkProxySettings(WebCore::SoupNetworkProxySettings(WebCore::SoupNetworkProxySettings::Mode::NoProxy)); + break; + case WEBKIT_NETWORK_PROXY_MODE_CUSTOM: + const auto& settings = webkitNetworkProxySettingsGetNetworkProxySettings(proxySettings); + if (settings.isEmpty()) { + g_warning("Invalid attempt to set custom network proxy settings with an empty WebKitNetworkProxySettings. Use " + "WEBKIT_NETWORK_PROXY_MODE_NO_PROXY to not use any proxy or WEBKIT_NETWORK_PROXY_MODE_DEFAULT to use the default system settings"); + } else + priv->processPool->setNetworkProxySettings(settings); + break; + } } typedef HashMap<DownloadProxy*, GRefPtr<WebKitDownload> > DownloadsMap; static DownloadsMap& downloadsMap() { - DEFINE_STATIC_LOCAL(DownloadsMap, downloads, ()); + static NeverDestroyed<DownloadsMap> downloads; return downloads; } @@ -377,29 +680,26 @@ static DownloadsMap& downloadsMap() */ WebKitDownload* webkit_web_context_download_uri(WebKitWebContext* context, const gchar* uri) { - g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); - g_return_val_if_fail(uri, 0); + g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr); + g_return_val_if_fail(uri, nullptr); - return webkitWebContextStartDownload(context, uri, 0); + GRefPtr<WebKitDownload> download = webkitWebContextStartDownload(context, uri, nullptr); + return download.leakRef(); } /** * webkit_web_context_get_cookie_manager: * @context: a #WebKitWebContext * - * Get the #WebKitCookieManager of @context. + * Get the #WebKitCookieManager of the @context's #WebKitWebsiteDataManager. * * Returns: (transfer none): the #WebKitCookieManager of @context. */ WebKitCookieManager* webkit_web_context_get_cookie_manager(WebKitWebContext* context) { - g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); + g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr); - WebKitWebContextPrivate* priv = context->priv; - if (!priv->cookieManager) - priv->cookieManager = adoptGRef(webkitCookieManagerCreate(priv->context->supplement<WebCookieManagerProxy>())); - - return priv->cookieManager.get(); + return webkit_website_data_manager_get_cookie_manager(context->priv->websiteDataManager.get()); } static void ensureFaviconDatabase(WebKitWebContext* context) @@ -408,7 +708,32 @@ static void ensureFaviconDatabase(WebKitWebContext* context) if (priv->faviconDatabase) return; - priv->faviconDatabase = adoptGRef(webkitFaviconDatabaseCreate(priv->context->iconDatabase())); + priv->faviconDatabase = adoptGRef(webkitFaviconDatabaseCreate(priv->processPool->iconDatabase())); +} + +static void webkitWebContextEnableIconDatabasePrivateBrowsingIfNeeded(WebKitWebContext* context, WebKitWebView* webView) +{ + if (webkit_web_context_is_ephemeral(context)) + return; + if (!webkit_web_view_is_ephemeral(webView)) + return; + + if (!context->priv->ephemeralPageCount) + context->priv->processPool->iconDatabase()->setPrivateBrowsingEnabled(true); + context->priv->ephemeralPageCount++; +} + +static void webkitWebContextDisableIconDatabasePrivateBrowsingIfNeeded(WebKitWebContext* context, WebKitWebView* webView) +{ + if (webkit_web_context_is_ephemeral(context)) + return; + if (!webkit_web_view_is_ephemeral(webView)) + return; + + ASSERT(context->priv->ephemeralPageCount); + context->priv->ephemeralPageCount--; + if (!context->priv->ephemeralPageCount) + context->priv->processPool->iconDatabase()->setPrivateBrowsingEnabled(false); } /** @@ -431,16 +756,16 @@ void webkit_web_context_set_favicon_database_directory(WebKitWebContext* context g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); WebKitWebContextPrivate* priv = context->priv; - WebIconDatabase* iconDatabase = priv->context->iconDatabase(); + WebIconDatabase* iconDatabase = priv->processPool->iconDatabase(); if (iconDatabase->isOpen()) return; ensureFaviconDatabase(context); // Use default if 0 is passed as parameter. - String directoryPath = WebCore::filenameToString(path); + String directoryPath = WebCore::stringFromFileSystemRepresentation(path); priv->faviconDatabaseDirectory = directoryPath.isEmpty() - ? priv->context->iconDatabasePath().utf8() + ? priv->processPool->iconDatabasePath().utf8() : directoryPath.utf8(); // Build the full path to the icon database file on disk. @@ -448,7 +773,10 @@ void webkit_web_context_set_favicon_database_directory(WebKitWebContext* context WebCore::IconDatabase::defaultDatabaseFilename().utf8().data(), nullptr)); // Setting the path will cause the icon database to be opened. - priv->context->setIconDatabasePath(WebCore::filenameToString(faviconDatabasePath.get())); + priv->processPool->setIconDatabasePath(WebCore::stringFromFileSystemRepresentation(faviconDatabasePath.get())); + + if (webkit_web_context_is_ephemeral(context)) + priv->processPool->iconDatabase()->setPrivateBrowsingEnabled(true); } /** @@ -528,7 +856,9 @@ void webkit_web_context_set_additional_plugins_directory(WebKitWebContext* conte g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail(directory); - context->priv->context->setAdditionalPluginsDirectory(WebCore::filenameToString(directory)); +#if ENABLE(NETSCAPE_PLUGIN_API) + context->priv->processPool->setAdditionalPluginsDirectory(WebCore::stringFromFileSystemRepresentation(directory)); +#endif } static void destroyPluginList(GList* plugins) @@ -536,12 +866,14 @@ static void destroyPluginList(GList* plugins) g_list_free_full(plugins, g_object_unref); } -static void webkitWebContextGetPluginThread(GTask* task, gpointer object, gpointer taskData, GCancellable*) +static void webkitWebContextGetPluginThread(GTask* task, gpointer object, gpointer /* taskData */, GCancellable*) { - Vector<PluginModuleInfo> plugins = WEBKIT_WEB_CONTEXT(object)->priv->context->pluginInfoStore().plugins(); GList* returnValue = 0; +#if ENABLE(NETSCAPE_PLUGIN_API) + Vector<PluginModuleInfo> plugins = WEBKIT_WEB_CONTEXT(object)->priv->processPool->pluginInfoStore().plugins(); for (size_t i = 0; i < plugins.size(); ++i) returnValue = g_list_prepend(returnValue, webkitPluginCreate(plugins[i])); +#endif g_task_return_pointer(task, returnValue, reinterpret_cast<GDestroyNotify>(destroyPluginList)); } @@ -642,8 +974,9 @@ void webkit_web_context_register_uri_scheme(WebKitWebContext* context, const cha g_return_if_fail(callback); RefPtr<WebKitURISchemeHandler> handler = adoptRef(new WebKitURISchemeHandler(callback, userData, destroyNotify)); - context->priv->uriSchemeHandlers.set(String::fromUTF8(scheme), handler.get()); - context->priv->requestManager->registerSchemeForCustomProtocol(String::fromUTF8(scheme)); + auto addResult = context->priv->uriSchemeHandlers.set(String::fromUTF8(scheme), handler.get()); + if (addResult.isNewEntry) + context->priv->processPool->registerSchemeForCustomProtocol(String::fromUTF8(scheme)); } /** @@ -659,7 +992,7 @@ gboolean webkit_web_context_get_spell_checking_enabled(WebKitWebContext* context g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), FALSE); #if ENABLE(SPELLCHECK) - return context->priv->textChecker->isSpellCheckingEnabled(); + return TextChecker::state().isContinuousSpellCheckingEnabled; #else return false; #endif @@ -677,7 +1010,7 @@ void webkit_web_context_set_spell_checking_enabled(WebKitWebContext* context, gb g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); #if ENABLE(SPELLCHECK) - context->priv->textChecker->setSpellCheckingEnabled(enabled); + TextChecker::setContinuousSpellCheckingEnabled(enabled); #endif } @@ -696,10 +1029,20 @@ void webkit_web_context_set_spell_checking_enabled(WebKitWebContext* context, gb */ const gchar* const* webkit_web_context_get_spell_checking_languages(WebKitWebContext* context) { - g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); + g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr); #if ENABLE(SPELLCHECK) - return context->priv->textChecker->getSpellCheckingLanguages(); + Vector<String> spellCheckingLanguages = TextChecker::loadedSpellCheckingLanguages(); + if (spellCheckingLanguages.isEmpty()) + return nullptr; + + static GRefPtr<GPtrArray> languagesToReturn; + languagesToReturn = adoptGRef(g_ptr_array_new_with_free_func(g_free)); + for (const auto& language : spellCheckingLanguages) + g_ptr_array_add(languagesToReturn.get(), g_strdup(language.utf8().data())); + g_ptr_array_add(languagesToReturn.get(), nullptr); + + return reinterpret_cast<char**>(languagesToReturn->pdata); #else return 0; #endif @@ -728,7 +1071,10 @@ void webkit_web_context_set_spell_checking_languages(WebKitWebContext* context, g_return_if_fail(languages); #if ENABLE(SPELLCHECK) - context->priv->textChecker->setSpellCheckingLanguages(languages); + Vector<String> spellCheckingLanguages; + for (size_t i = 0; languages[i]; ++i) + spellCheckingLanguages.append(String::fromUTF8(languages[i])); + TextChecker::setSpellCheckingLanguages(spellCheckingLanguages); #endif } @@ -750,11 +1096,14 @@ void webkit_web_context_set_preferred_languages(WebKitWebContext* context, const return; Vector<String> languages; - for (size_t i = 0; languageList[i]; ++i) - languages.append(String::fromUTF8(languageList[i]).lower().replace("_", "-")); - + for (size_t i = 0; languageList[i]; ++i) { + // Do not propagate the C locale to WebCore. + if (!g_ascii_strcasecmp(languageList[i], "C") || !g_ascii_strcasecmp(languageList[i], "POSIX")) + languages.append(ASCIILiteral("en-us")); + else + languages.append(String::fromUTF8(languageList[i]).convertToASCIILowercase().replace("_", "-")); + } WebCore::overrideUserPreferredLanguages(languages); - WebCore::languageDidChange(); } /** @@ -773,8 +1122,8 @@ void webkit_web_context_set_tls_errors_policy(WebKitWebContext* context, WebKitT context->priv->tlsErrorsPolicy = policy; bool ignoreTLSErrors = policy == WEBKIT_TLS_ERRORS_POLICY_IGNORE; - if (context->priv->context->ignoreTLSErrors() != ignoreTLSErrors) - context->priv->context->setIgnoreTLSErrors(ignoreTLSErrors); + if (context->priv->processPool->ignoreTLSErrors() != ignoreTLSErrors) + context->priv->processPool->setIgnoreTLSErrors(ignoreTLSErrors); } /** @@ -842,13 +1191,19 @@ void webkit_web_context_set_web_extensions_initialization_user_data(WebKitWebCon * Set the directory where disk cache files will be stored * This method must be called before loading anything in this context, otherwise * it will not have any effect. + * + * Note that this method overrides the directory set in the #WebKitWebsiteDataManager, + * but it doesn't change the value returned by webkit_website_data_manager_get_disk_cache_directory() + * since the #WebKitWebsiteDataManager is immutable. + * + * Deprecated: 2.10. Use webkit_web_context_new_with_website_data_manager() instead. */ void webkit_web_context_set_disk_cache_directory(WebKitWebContext* context, const char* directory) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail(directory); - context->priv->context->setDiskCacheDirectory(WebCore::filenameToString(directory)); + context->priv->processPool->configuration().setDiskCacheDirectory(WebCore::pathByAppendingComponent(WebCore::stringFromFileSystemRepresentation(directory), networkCacheSubdirectory)); } /** @@ -864,29 +1219,29 @@ void webkit_web_context_prefetch_dns(WebKitWebContext* context, const char* host g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail(hostname); - ImmutableDictionary::MapType message; + API::Dictionary::MapType message; message.set(String::fromUTF8("Hostname"), API::String::create(String::fromUTF8(hostname))); - context->priv->context->postMessageToInjectedBundle(String::fromUTF8("PrefetchDNS"), ImmutableDictionary::create(std::move(message)).get()); + context->priv->processPool->postMessageToInjectedBundle(String::fromUTF8("PrefetchDNS"), API::Dictionary::create(WTFMove(message)).ptr()); } /** * webkit_web_context_allow_tls_certificate_for_host: * @context: a #WebKitWebContext - * @info: a #WebKitCertificateInfo + * @certificate: a #GTlsCertificate * @host: the host for which a certificate is to be allowed * * Ignore further TLS errors on the @host for the certificate present in @info. * - * Since: 2.4 + * Since: 2.6 */ -void webkit_web_context_allow_tls_certificate_for_host(WebKitWebContext* context, WebKitCertificateInfo* info, const gchar* host) +void webkit_web_context_allow_tls_certificate_for_host(WebKitWebContext* context, GTlsCertificate* certificate, const gchar* host) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); - g_return_if_fail(info); + g_return_if_fail(G_IS_TLS_CERTIFICATE(certificate)); g_return_if_fail(host); - RefPtr<WebCertificateInfo> webCertificateInfo = WebCertificateInfo::create(webkitCertificateInfoGetCertificateInfo(info)); - context->priv->context->allowSpecificHTTPSCertificateForHost(webCertificateInfo.get(), String::fromUTF8(host)); + RefPtr<WebCertificateInfo> webCertificateInfo = WebCertificateInfo::create(WebCore::CertificateInfo(certificate, static_cast<GTlsCertificateFlags>(0))); + context->priv->processPool->allowSpecificHTTPSCertificateForHost(webCertificateInfo.get(), String::fromUTF8(host)); } /** @@ -910,7 +1265,7 @@ void webkit_web_context_allow_tls_certificate_for_host(WebKitWebContext* context * the rest of the WebViews in the application will still function * normally. * - * This method **must be called before any other functions**, + * This method **must be called before any web process has been created**, * as early as possible in your application. Calling it later will make * your application crash. * @@ -920,24 +1275,18 @@ void webkit_web_context_set_process_model(WebKitWebContext* context, WebKitProce { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); - ProcessModel newProcessModel; + if (processModel == context->priv->processModel) + return; - switch (processModel) { + context->priv->processModel = processModel; + switch (context->priv->processModel) { case WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS: - newProcessModel = ProcessModelSharedSecondaryProcess; + context->priv->processPool->setMaximumNumberOfProcesses(1); break; case WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES: - newProcessModel = ProcessModelMultipleSecondaryProcesses; + context->priv->processPool->setMaximumNumberOfProcesses(context->priv->processCountLimit); break; - default: - g_assert_not_reached(); } - - if (newProcessModel == context->priv->context->processModel()) - return; - - context->priv->context->setUsesNetworkProcess(newProcessModel == ProcessModelMultipleSecondaryProcesses); - context->priv->context->setProcessModel(newProcessModel); } /** @@ -955,14 +1304,98 @@ WebKitProcessModel webkit_web_context_get_process_model(WebKitWebContext* contex { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS); - switch (context->priv->context->processModel()) { - case ProcessModelSharedSecondaryProcess: - return WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS; - case ProcessModelMultipleSecondaryProcesses: - return WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES; - default: - g_assert_not_reached(); - } + return context->priv->processModel; +} + +/** + * webkit_web_context_set_web_process_count_limit: + * @context: the #WebKitWebContext + * @limit: the maximum number of web processes + * + * Sets the maximum number of web processes that can be created at the same time for the @context. + * The default value is 0 and means no limit. + * + * This method **must be called before any web process has been created**, + * as early as possible in your application. Calling it later will make + * your application crash. + * + * Since: 2.10 + */ +void webkit_web_context_set_web_process_count_limit(WebKitWebContext* context, guint limit) +{ + g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); + + if (context->priv->processCountLimit == limit) + return; + + context->priv->processCountLimit = limit; + if (context->priv->processModel != WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS) + context->priv->processPool->setMaximumNumberOfProcesses(limit); +} + +/** + * webkit_web_context_get_web_process_count_limit: + * @context: the #WebKitWebContext + * + * Gets the maximum number of web processes that can be created at the same time for the @context. + * + * Returns: the maximum limit of web processes, or 0 if there isn't a limit. + * + * Since: 2.10 + */ +guint webkit_web_context_get_web_process_count_limit(WebKitWebContext* context) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); + + return context->priv->processCountLimit; +} + +static void addOriginToMap(WebKitSecurityOrigin* origin, HashMap<String, RefPtr<API::Object>>* map, bool allowed) +{ + String string = webkitSecurityOriginGetSecurityOrigin(origin).toString(); + if (string != "null") + map->set(string, API::Boolean::create(allowed)); +} + +/** + * webkit_web_context_initialize_notification_permissions: + * @context: the #WebKitWebContext + * @allowed_origins: (element-type WebKitSecurityOrigin): a #GList of security origins + * @disallowed_origins: (element-type WebKitSecurityOrigin): a #GList of security origins + * + * Sets initial desktop notification permissions for the @context. + * @allowed_origins and @disallowed_origins must each be #GList of + * #WebKitSecurityOrigin objects representing origins that will, + * respectively, either always or never have permission to show desktop + * notifications. No #WebKitNotificationPermissionRequest will ever be + * generated for any of the security origins represented in + * @allowed_origins or @disallowed_origins. This function is necessary + * because some webpages proactively check whether they have permission + * to display notifications without ever creating a permission request. + * + * This function only affects web processes that have not already been + * created. The best time to call it is when handling + * #WebKitWebContext::initialize-notification-permissions so as to + * ensure that new web processes receive the most recent set of + * permissions. + * + * Since: 2.16 + */ +void webkit_web_context_initialize_notification_permissions(WebKitWebContext* context, GList* allowedOrigins, GList* disallowedOrigins) +{ + HashMap<String, RefPtr<API::Object>> map; + g_list_foreach(allowedOrigins, [](gpointer data, gpointer userData) { + addOriginToMap(static_cast<WebKitSecurityOrigin*>(data), static_cast<HashMap<String, RefPtr<API::Object>>*>(userData), true); + }, &map); + g_list_foreach(disallowedOrigins, [](gpointer data, gpointer userData) { + addOriginToMap(static_cast<WebKitSecurityOrigin*>(data), static_cast<HashMap<String, RefPtr<API::Object>>*>(userData), false); + }, &map); + context->priv->notificationProvider->setNotificationPermissions(WTFMove(map)); +} + +void webkitWebContextInitializeNotificationPermissions(WebKitWebContext* context) +{ + g_signal_emit(context, signals[INITIALIZE_NOTIFICATION_PERMISSIONS], 0); } WebKitDownload* webkitWebContextGetOrCreateDownload(DownloadProxy* downloadProxy) @@ -979,10 +1412,7 @@ WebKitDownload* webkitWebContextGetOrCreateDownload(DownloadProxy* downloadProxy WebKitDownload* webkitWebContextStartDownload(WebKitWebContext* context, const char* uri, WebPageProxy* initiatingPage) { WebCore::ResourceRequest request(String::fromUTF8(uri)); - DownloadProxy* downloadProxy = context->priv->context->download(initiatingPage, request); - WebKitDownload* download = webkitDownloadCreateForRequest(downloadProxy, request); - downloadsMap().set(downloadProxy, download); - return download; + return webkitWebContextGetOrCreateDownload(context->priv->processPool->download(initiatingPage, request)); } void webkitWebContextRemoveDownload(DownloadProxy* downloadProxy) @@ -1003,21 +1433,16 @@ GVariant* webkitWebContextInitializeWebExtensions(WebKitWebContext* context) context->priv->webExtensionsInitializationUserData.get()); } -WebContext* webkitWebContextGetContext(WebKitWebContext* context) +WebProcessPool& webkitWebContextGetProcessPool(WebKitWebContext* context) { g_assert(WEBKIT_IS_WEB_CONTEXT(context)); - return context->priv->context.get(); -} - -WebSoupCustomProtocolRequestManager* webkitWebContextGetRequestManager(WebKitWebContext* context) -{ - return context->priv->requestManager.get(); + return *context->priv->processPool; } -void webkitWebContextStartLoadingCustomProtocol(WebKitWebContext* context, uint64_t customProtocolID, API::URLRequest* urlRequest) +void webkitWebContextStartLoadingCustomProtocol(WebKitWebContext* context, uint64_t customProtocolID, const WebCore::ResourceRequest& resourceRequest, CustomProtocolManagerProxy& manager) { - GRefPtr<WebKitURISchemeRequest> request = adoptGRef(webkitURISchemeRequestCreate(customProtocolID, context, urlRequest)); + GRefPtr<WebKitURISchemeRequest> request = adoptGRef(webkitURISchemeRequestCreate(customProtocolID, context, resourceRequest, manager)); String scheme(String::fromUTF8(webkit_uri_scheme_request_get_scheme(request.get()))); RefPtr<WebKitURISchemeHandler> handler = context->priv->uriSchemeHandlers.get(scheme); ASSERT(handler.get()); @@ -1036,27 +1461,54 @@ void webkitWebContextStopLoadingCustomProtocol(WebKitWebContext* context, uint64 webkitURISchemeRequestCancel(request.get()); } +void webkitWebContextInvalidateCustomProtocolRequests(WebKitWebContext* context, CustomProtocolManagerProxy& manager) +{ + Vector<GRefPtr<WebKitURISchemeRequest>> requests; + copyValuesToVector(context->priv->uriSchemeRequests, requests); + for (auto& request : requests) { + if (webkitURISchemeRequestGetManager(request.get()) == &manager) + webkitURISchemeRequestInvalidate(request.get()); + } +} + void webkitWebContextDidFinishLoadingCustomProtocol(WebKitWebContext* context, uint64_t customProtocolID) { context->priv->uriSchemeRequests.remove(customProtocolID); } -void webkitWebContextCreatePageForWebView(WebKitWebContext* context, WebKitWebView* webView, WebKitWebViewGroup* webViewGroup, WebKitWebView* relatedView) +bool webkitWebContextIsLoadingCustomProtocol(WebKitWebContext* context, uint64_t customProtocolID) +{ + return context->priv->uriSchemeRequests.get(customProtocolID); +} + +void webkitWebContextCreatePageForWebView(WebKitWebContext* context, WebKitWebView* webView, WebKitUserContentManager* userContentManager, WebKitWebView* relatedView) { WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(webView); - WebPageGroup* pageGroup = webViewGroup ? webkitWebViewGroupGetPageGroup(webViewGroup) : 0; - WebPageProxy* relatedPage = relatedView ? webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(relatedView)) : nullptr; - webkitWebViewBaseCreateWebPage(webViewBase, context->priv->context.get(), pageGroup, relatedPage); + + // FIXME: icon database private mode is global, not per page, so while there are + // pages in private mode we need to enable the private mode in the icon database. + webkitWebContextEnableIconDatabasePrivateBrowsingIfNeeded(context, webView); + + auto pageConfiguration = API::PageConfiguration::create(); + pageConfiguration->setProcessPool(context->priv->processPool.get()); + pageConfiguration->setPreferences(webkitSettingsGetPreferences(webkit_web_view_get_settings(webView))); + pageConfiguration->setRelatedPage(relatedView ? webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(relatedView)) : nullptr); + pageConfiguration->setUserContentController(userContentManager ? webkitUserContentManagerGetUserContentControllerProxy(userContentManager) : nullptr); + + WebKitWebsiteDataManager* manager = webkitWebViewGetWebsiteDataManager(webView); + if (!manager) + manager = context->priv->websiteDataManager.get(); + pageConfiguration->setWebsiteDataStore(&webkitWebsiteDataManagerGetDataStore(manager)); + pageConfiguration->setSessionID(pageConfiguration->websiteDataStore()->websiteDataStore().sessionID()); + webkitWebViewBaseCreateWebPage(webViewBase, WTFMove(pageConfiguration)); WebPageProxy* page = webkitWebViewBaseGetPage(webViewBase); context->priv->webViews.set(page->pageID(), webView); - - if (!pageGroup && !context->priv->defaultWebViewGroup) - context->priv->defaultWebViewGroup = adoptGRef(webkitWebViewGroupCreate(&page->pageGroup())); } void webkitWebContextWebViewDestroyed(WebKitWebContext* context, WebKitWebView* webView) { + webkitWebContextDisableIconDatabasePrivateBrowsingIfNeeded(context, webView); WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)); context->priv->webViews.remove(page->pageID()); } @@ -1065,8 +1517,3 @@ WebKitWebView* webkitWebContextGetWebViewForPage(WebKitWebContext* context, WebP { return page ? context->priv->webViews.get(page->pageID()) : 0; } - -WebKitWebViewGroup* webkitWebContextGetDefaultWebViewGroup(WebKitWebContext* context) -{ - return context->priv->defaultWebViewGroup.get(); -} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h index 3ce281b9b..5ae166655 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h @@ -25,13 +25,14 @@ #define WebKitWebContext_h #include <glib-object.h> -#include <webkit2/WebKitCertificateInfo.h> #include <webkit2/WebKitCookieManager.h> #include <webkit2/WebKitDefines.h> #include <webkit2/WebKitDownload.h> #include <webkit2/WebKitFaviconDatabase.h> +#include <webkit2/WebKitNetworkProxySettings.h> #include <webkit2/WebKitSecurityManager.h> #include <webkit2/WebKitURISchemeRequest.h> +#include <webkit2/WebKitWebsiteDataManager.h> G_BEGIN_DECLS @@ -104,6 +105,22 @@ typedef enum { } WebKitTLSErrorsPolicy; /** + * WebKitNetworkProxyMode: + * @WEBKIT_NETWORK_PROXY_MODE_DEFAULT: Use the default proxy of the system. + * @WEBKIT_NETWORK_PROXY_MODE_NO_PROXY: Do not use any proxy. + * @WEBKIT_NETWORK_PROXY_MODE_CUSTOM: Use custom proxy settings. + * + * Enum values used to set the network proxy mode. + * + * Since: 2.16 + */ +typedef enum { + WEBKIT_NETWORK_PROXY_MODE_DEFAULT, + WEBKIT_NETWORK_PROXY_MODE_NO_PROXY, + WEBKIT_NETWORK_PROXY_MODE_CUSTOM +} WebKitNetworkProxyMode; + +/** * WebKitURISchemeRequestCallback: * @request: the #WebKitURISchemeRequest * @user_data: user data passed to the callback @@ -128,14 +145,16 @@ struct _WebKitWebContext { struct _WebKitWebContextClass { GObjectClass parent; + void (* download_started) (WebKitWebContext *context, + WebKitDownload *download); + void (* initialize_web_extensions) (WebKitWebContext *context); + void (* initialize_notification_permissions) (WebKitWebContext *context); + void (*_webkit_reserved0) (void); void (*_webkit_reserved1) (void); void (*_webkit_reserved2) (void); void (*_webkit_reserved3) (void); void (*_webkit_reserved4) (void); - void (*_webkit_reserved5) (void); - void (*_webkit_reserved6) (void); - void (*_webkit_reserved7) (void); }; WEBKIT_API GType @@ -144,6 +163,21 @@ webkit_web_context_get_type (void); WEBKIT_API WebKitWebContext * webkit_web_context_get_default (void); +WEBKIT_API WebKitWebContext * +webkit_web_context_new (void); + +WEBKIT_API WebKitWebContext * +webkit_web_context_new_ephemeral (void); + +WEBKIT_API WebKitWebContext * +webkit_web_context_new_with_website_data_manager (WebKitWebsiteDataManager *manager); + +WEBKIT_API WebKitWebsiteDataManager * +webkit_web_context_get_website_data_manager (WebKitWebContext *context); + +WEBKIT_API gboolean +webkit_web_context_is_ephemeral (WebKitWebContext *context); + WEBKIT_API void webkit_web_context_set_cache_model (WebKitWebContext *context, WebKitCacheModel cache_model); @@ -151,8 +185,20 @@ WEBKIT_API WebKitCacheModel webkit_web_context_get_cache_model (WebKitWebContext *context); WEBKIT_API void +webkit_web_context_set_web_process_count_limit (WebKitWebContext *context, + guint limit); + +WEBKIT_API guint +webkit_web_context_get_web_process_count_limit (WebKitWebContext *context); + +WEBKIT_API void webkit_web_context_clear_cache (WebKitWebContext *context); +WEBKIT_API void +webkit_web_context_set_network_proxy_settings (WebKitWebContext *context, + WebKitNetworkProxyMode proxy_mode, + WebKitNetworkProxySettings *proxy_settings); + WEBKIT_API WebKitDownload * webkit_web_context_download_uri (WebKitWebContext *context, const gchar *uri); @@ -230,13 +276,13 @@ WEBKIT_API void webkit_web_context_prefetch_dns (WebKitWebContext *context, const gchar *hostname); -WEBKIT_API void +WEBKIT_DEPRECATED_FOR(webkit_web_context_new_with_website_data_manager) void webkit_web_context_set_disk_cache_directory (WebKitWebContext *context, const gchar *directory); WEBKIT_API void webkit_web_context_allow_tls_certificate_for_host (WebKitWebContext *context, - WebKitCertificateInfo *info, + GTlsCertificate *certificate, const gchar *host); WEBKIT_API void @@ -246,6 +292,12 @@ webkit_web_context_set_process_model (WebKitWebContext WEBKIT_API WebKitProcessModel webkit_web_context_get_process_model (WebKitWebContext *context); +WEBKIT_API void +webkit_web_context_initialize_notification_permissions + (WebKitWebContext *context, + GList *allowed_origins, + GList *disallowed_origins); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContextPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContextPrivate.h index 06474a1ef..c2b29ac74 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContextPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContextPrivate.h @@ -26,26 +26,28 @@ #ifndef WebKitWebContextPrivate_h #define WebKitWebContextPrivate_h +#include "CustomProtocolManagerProxy.h" #include "DownloadProxy.h" -#include "WebContext.h" #include "WebKitPrivate.h" +#include "WebKitUserContentManager.h" #include "WebKitWebContext.h" -#include "WebKitWebViewGroup.h" -#include "WebSoupCustomProtocolRequestManager.h" +#include "WebProcessPool.h" +#include <WebCore/ResourceRequest.h> -WebKit::WebContext* webkitWebContextGetContext(WebKitWebContext*); +WebKit::WebProcessPool& webkitWebContextGetProcessPool(WebKitWebContext*); WebKitDownload* webkitWebContextGetOrCreateDownload(WebKit::DownloadProxy*); WebKitDownload* webkitWebContextStartDownload(WebKitWebContext*, const char* uri, WebKit::WebPageProxy*); void webkitWebContextRemoveDownload(WebKit::DownloadProxy*); void webkitWebContextDownloadStarted(WebKitWebContext*, WebKitDownload*); -WebKit::WebSoupCustomProtocolRequestManager* webkitWebContextGetRequestManager(WebKitWebContext*); -void webkitWebContextStartLoadingCustomProtocol(WebKitWebContext*, uint64_t customProtocolID, API::URLRequest*); +void webkitWebContextStartLoadingCustomProtocol(WebKitWebContext*, uint64_t customProtocolID, const WebCore::ResourceRequest&, WebKit::CustomProtocolManagerProxy&); void webkitWebContextStopLoadingCustomProtocol(WebKitWebContext*, uint64_t customProtocolID); +void webkitWebContextInvalidateCustomProtocolRequests(WebKitWebContext*, WebKit::CustomProtocolManagerProxy&); void webkitWebContextDidFinishLoadingCustomProtocol(WebKitWebContext*, uint64_t customProtocolID); -void webkitWebContextCreatePageForWebView(WebKitWebContext*, WebKitWebView*, WebKitWebViewGroup*, WebKitWebView*); +bool webkitWebContextIsLoadingCustomProtocol(WebKitWebContext*, uint64_t customProtocolID); +void webkitWebContextCreatePageForWebView(WebKitWebContext*, WebKitWebView*, WebKitUserContentManager*, WebKitWebView*); void webkitWebContextWebViewDestroyed(WebKitWebContext*, WebKitWebView*); WebKitWebView* webkitWebContextGetWebViewForPage(WebKitWebContext*, WebKit::WebPageProxy*); -WebKitWebViewGroup* webkitWebContextGetDefaultWebViewGroup(WebKitWebContext*); GVariant* webkitWebContextInitializeWebExtensions(WebKitWebContext*); +void webkitWebContextInitializeNotificationPermissions(WebKitWebContext*); #endif // WebKitWebContextPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.cpp index 083d27c84..522e5b635 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.cpp @@ -24,7 +24,7 @@ #include "WebKitMarshal.h" #include "WebKitWebInspectorPrivate.h" #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -72,7 +72,8 @@ enum { PROP_0, PROP_INSPECTED_URI, - PROP_ATTACHED_HEIGHT + PROP_ATTACHED_HEIGHT, + PROP_CAN_ATTACH }; struct _WebKitWebInspectorPrivate { @@ -84,6 +85,7 @@ struct _WebKitWebInspectorPrivate { RefPtr<WebInspectorProxy> webInspector; CString inspectedURI; unsigned attachedHeight; + bool canAttach; }; WEBKIT_DEFINE_TYPE(WebKitWebInspector, webkit_web_inspector, G_TYPE_OBJECT) @@ -101,6 +103,9 @@ static void webkitWebInspectorGetProperty(GObject* object, guint propId, GValue* case PROP_ATTACHED_HEIGHT: g_value_set_uint(value, webkit_web_inspector_get_attached_height(inspector)); break; + case PROP_CAN_ATTACH: + g_value_set_boolean(value, webkit_web_inspector_get_can_attach(inspector)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); } @@ -137,6 +142,24 @@ static void webkit_web_inspector_class_init(WebKitWebInspectorClass* findClass) WEBKIT_PARAM_READABLE)); /** + * WebKitWebInspector:can-attach: + * + * Whether the @inspector can be attached to the same window that contains + * the inspected view. + * + * Since: 2.8 + */ + g_object_class_install_property( + gObjectClass, + PROP_CAN_ATTACH, + g_param_spec_boolean( + "can-attach", + _("Can Attach"), + _("Whether the inspector can be attached to the same window that contains the inspected view"), + FALSE, + WEBKIT_PARAM_READABLE)); + + /** * WebKitWebInspector::open-window: * @inspector: the #WebKitWebInspector on which the signal is emitted * @@ -217,7 +240,7 @@ static void webkit_web_inspector_class_init(WebKitWebInspectorClass* findClass) * if you want to attach the inspector view yourself (for example, to add * the inspector view to a browser tab). * - * To prevent the inspector vew from being attached you can connect to this + * To prevent the inspector view from being attached you can connect to this * signal and simply return %TRUE. * * Returns: %TRUE to stop other handlers from being invoked for the event. @@ -295,7 +318,7 @@ static bool attach(WKInspectorRef, const void* clientInfo) return returnValue; } -static bool detach(WKInspectorRef inspector, const void* clientInfo) +static bool detach(WKInspectorRef, const void* clientInfo) { gboolean returnValue; g_signal_emit(WEBKIT_WEB_INSPECTOR(clientInfo), signals[DETACH], 0, &returnValue); @@ -311,6 +334,15 @@ static void didChangeAttachedHeight(WKInspectorRef, unsigned height, const void* g_object_notify(G_OBJECT(inspector), "attached-height"); } +static void didChangeAttachAvailability(WKInspectorRef, bool available, const void* clientInfo) +{ + WebKitWebInspector* inspector = WEBKIT_WEB_INSPECTOR(clientInfo); + if (inspector->priv->canAttach == available) + return; + inspector->priv->canAttach = available; + g_object_notify(G_OBJECT(clientInfo), "can-attach"); +} + WebKitWebInspector* webkitWebInspectorCreate(WebInspectorProxy* webInspector) { WebKitWebInspector* inspector = WEBKIT_WEB_INSPECTOR(g_object_new(WEBKIT_TYPE_WEB_INSPECTOR, NULL)); @@ -328,7 +360,8 @@ WebKitWebInspector* webkitWebInspectorCreate(WebInspectorProxy* webInspector) attach, detach, didChangeAttachedHeight, - nullptr // didChangeAttachedWidth + nullptr, // didChangeAttachedWidth + didChangeAttachAvailability }; WKInspectorSetInspectorClientGtk(toAPI(webInspector), &wkInspectorClientGtk.base); @@ -371,6 +404,25 @@ const char* webkit_web_inspector_get_inspected_uri(WebKitWebInspector* inspector } /** + * webkit_web_inspector_get_can_attach: + * @inspector: a #WebKitWebInspector + * + * Whether the @inspector can be attached to the same window that contains + * the inspected view. + * + * Returns: %TRUE if there is enough room for the inspector view inside the + * window that contains the inspected view, or %FALSE otherwise. + * + * Since: 2.8 + */ +gboolean webkit_web_inspector_get_can_attach(WebKitWebInspector* inspector) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_INSPECTOR(inspector), FALSE); + + return inspector->priv->canAttach; +} + +/** * webkit_web_inspector_is_attached: * @inspector: a #WebKitWebInspector * diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.h index 67f0f4957..686f949ac 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.h @@ -83,6 +83,9 @@ webkit_web_inspector_close (WebKitWebInspector *inspector); WEBKIT_API guint webkit_web_inspector_get_attached_height (WebKitWebInspector *inspector); +WEBKIT_API gboolean +webkit_web_inspector_get_can_attach (WebKitWebInspector* inspector); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp index b4e11e90c..7dbd804ad 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp @@ -26,7 +26,7 @@ #include "WebKitURIRequest.h" #include "WebKitWebResourcePrivate.h" #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -53,6 +53,7 @@ enum { RECEIVED_DATA, FINISHED, FAILED, + FAILED_WITH_TLS_ERRORS, LAST_SIGNAL }; @@ -190,13 +191,34 @@ static void webkit_web_resource_class_init(WebKitWebResourceClass* resourceClass * load operation. */ signals[FAILED] = - g_signal_new("failed", - G_TYPE_FROM_CLASS(objectClass), - G_SIGNAL_RUN_LAST, - 0, 0, 0, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); + g_signal_new( + "failed", + G_TYPE_FROM_CLASS(objectClass), + G_SIGNAL_RUN_LAST, + 0, 0, 0, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + G_TYPE_ERROR | G_SIGNAL_TYPE_STATIC_SCOPE); + + /** + * WebKitWebResource::failed-with-tls-errors: + * @resource: the #WebKitWebResource + * @certificate: a #GTlsCertificate + * @errors: a #GTlsCertificateFlags with the verification status of @certificate + * + * This signal is emitted when a TLS error occurs during the resource load operation. + * + * Since: 2.8 + */ + signals[FAILED_WITH_TLS_ERRORS] = + g_signal_new("failed-with-tls-errors", + G_TYPE_FROM_CLASS(objectClass), + G_SIGNAL_RUN_LAST, + 0, nullptr, nullptr, + g_cclosure_marshal_generic, + G_TYPE_NONE, 2, + G_TYPE_TLS_CERTIFICATE, + G_TYPE_TLS_CERTIFICATE_FLAGS); } static void webkitWebResourceUpdateURI(WebKitWebResource* resource, const CString& requestURI) @@ -246,6 +268,12 @@ void webkitWebResourceFailed(WebKitWebResource* resource, GError* error) g_signal_emit(resource, signals[FINISHED], 0, NULL); } +void webkitWebResourceFailedWithTLSErrors(WebKitWebResource* resource, GTlsCertificateFlags tlsErrors, GTlsCertificate* certificate) +{ + g_signal_emit(resource, signals[FAILED_WITH_TLS_ERRORS], 0, certificate, tlsErrors); + g_signal_emit(resource, signals[FINISHED], 0, nullptr); +} + WebFrameProxy* webkitWebResourceGetFrame(WebKitWebResource* resource) { return resource->priv->frame.get(); @@ -314,12 +342,11 @@ struct ResourceGetDataAsyncData { }; WEBKIT_DEFINE_ASYNC_DATA_STRUCT(ResourceGetDataAsyncData) -static void resourceDataCallback(WKDataRef wkData, WKErrorRef, void* context) +static void resourceDataCallback(API::Data* wkData, GTask* task) { - GRefPtr<GTask> task = adoptGRef(G_TASK(context)); - ResourceGetDataAsyncData* data = static_cast<ResourceGetDataAsyncData*>(g_task_get_task_data(task.get())); - data->webData = toImpl(wkData); - g_task_return_boolean(task.get(), TRUE); + ResourceGetDataAsyncData* data = static_cast<ResourceGetDataAsyncData*>(g_task_get_task_data(task)); + data->webData = wkData; + g_task_return_boolean(task, TRUE); } /** @@ -341,10 +368,14 @@ void webkit_web_resource_get_data(WebKitWebResource* resource, GCancellable* can GTask* task = g_task_new(resource, cancellable, callback, userData); g_task_set_task_data(task, createResourceGetDataAsyncData(), reinterpret_cast<GDestroyNotify>(destroyResourceGetDataAsyncData)); if (resource->priv->isMainResource) - resource->priv->frame->getMainResourceData(DataCallback::create(task, resourceDataCallback)); + resource->priv->frame->getMainResourceData([task](API::Data* data, CallbackBase::Error) { + resourceDataCallback(data, adoptGRef(task).get()); + }); else { String url = String::fromUTF8(resource->priv->uri.data()); - resource->priv->frame->getResourceData(API::URL::create(url).get(), DataCallback::create(task, resourceDataCallback)); + resource->priv->frame->getResourceData(API::URL::create(url).ptr(), [task](API::Data* data, CallbackBase::Error) { + resourceDataCallback(data, adoptGRef(task).get()); + }); } } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h index 82e2d8f5a..de9e36b5f 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h @@ -29,6 +29,7 @@ void webkitWebResourceSetResponse(WebKitWebResource*, WebKitURIResponse*); void webkitWebResourceNotifyProgress(WebKitWebResource*, guint64 bytesReceived); void webkitWebResourceFinished(WebKitWebResource*); void webkitWebResourceFailed(WebKitWebResource*, GError*); +void webkitWebResourceFailedWithTLSErrors(WebKitWebResource*, GTlsCertificateFlags, GTlsCertificate*); WebKit::WebFrameProxy* webkitWebResourceGetFrame(WebKitWebResource*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp index 0abb35e12..eeb439bb2 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2011 Igalia S.L. * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved. + * Copyright (C) 2014 Collabora Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,6 +23,7 @@ #include "WebKitWebView.h" #include "APIData.h" +#include "APISerializedScriptValue.h" #include "ImageOptions.h" #include "WebCertificateInfo.h" #include "WebContextMenuItem.h" @@ -29,25 +31,28 @@ #include "WebKitAuthenticationDialog.h" #include "WebKitAuthenticationRequestPrivate.h" #include "WebKitBackForwardListPrivate.h" -#include "WebKitCertificateInfoPrivate.h" #include "WebKitContextMenuClient.h" #include "WebKitContextMenuItemPrivate.h" #include "WebKitContextMenuPrivate.h" #include "WebKitDownloadPrivate.h" +#include "WebKitEditorStatePrivate.h" #include "WebKitEnumTypes.h" #include "WebKitError.h" #include "WebKitFaviconDatabasePrivate.h" #include "WebKitFormClient.h" #include "WebKitFullscreenClient.h" #include "WebKitHitTestResultPrivate.h" +#include "WebKitInstallMissingMediaPluginsPermissionRequestPrivate.h" #include "WebKitJavascriptResultPrivate.h" #include "WebKitLoaderClient.h" #include "WebKitMarshal.h" +#include "WebKitNotificationPrivate.h" #include "WebKitPolicyClient.h" #include "WebKitPrintOperationPrivate.h" #include "WebKitPrivate.h" #include "WebKitResponsePolicyDecision.h" #include "WebKitScriptDialogPrivate.h" +#include "WebKitSettingsPrivate.h" #include "WebKitUIClient.h" #include "WebKitURIRequestPrivate.h" #include "WebKitURIResponsePrivate.h" @@ -55,20 +60,24 @@ #include "WebKitWebInspectorPrivate.h" #include "WebKitWebResourcePrivate.h" #include "WebKitWebViewBasePrivate.h" -#include "WebKitWebViewGroupPrivate.h" #include "WebKitWebViewPrivate.h" +#include "WebKitWebViewSessionStatePrivate.h" +#include "WebKitWebsiteDataManagerPrivate.h" #include "WebKitWindowPropertiesPrivate.h" #include <JavaScriptCore/APICast.h> #include <WebCore/CertificateInfo.h> -#include <WebCore/DragIcon.h> #include <WebCore/GUniquePtrGtk.h> #include <WebCore/GUniquePtrSoup.h> #include <WebCore/GtkUtilities.h> #include <WebCore/RefPtrCairo.h> #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> +#if USE(LIBNOTIFY) +#include <libnotify/notify.h> +#endif + using namespace WebKit; using namespace WebCore; @@ -124,6 +133,10 @@ enum { AUTHENTICATE, + SHOW_NOTIFICATION, + + RUN_COLOR_CHOOSER, + LAST_SIGNAL }; @@ -132,19 +145,24 @@ enum { PROP_WEB_CONTEXT, PROP_RELATED_VIEW, - PROP_GROUP, + PROP_SETTINGS, + PROP_USER_CONTENT_MANAGER, PROP_TITLE, PROP_ESTIMATED_LOAD_PROGRESS, PROP_FAVICON, PROP_URI, PROP_ZOOM_LEVEL, PROP_IS_LOADING, - PROP_VIEW_MODE + PROP_IS_PLAYING_AUDIO, + PROP_IS_EPHEMERAL, + PROP_EDITABLE }; typedef HashMap<uint64_t, GRefPtr<WebKitWebResource> > LoadingResourcesMap; typedef HashMap<uint64_t, GRefPtr<GTask> > SnapshotResultsMap; +class PageLoadStateObserver; + struct _WebKitWebViewPrivate { ~_WebKitWebViewPrivate() { @@ -156,24 +174,21 @@ struct _WebKitWebViewPrivate { g_main_loop_quit(modalLoop.get()); } - WebKitWebContext* context; WebKitWebView* relatedView; CString title; CString customTextEncoding; - double estimatedLoadProgress; CString activeURI; bool isLoading; - WebKitViewMode viewMode; + bool isEphemeral; - bool waitingForMainResource; - unsigned long mainResourceResponseHandlerID; - WebKitLoadEvent lastDelayedEvent; + std::unique_ptr<PageLoadStateObserver> loadObserver; GRefPtr<WebKitBackForwardList> backForwardList; GRefPtr<WebKitSettings> settings; - unsigned long settingsChangedHandlerID; - GRefPtr<WebKitWebViewGroup> group; + GRefPtr<WebKitUserContentManager> userContentManager; + GRefPtr<WebKitWebContext> context; GRefPtr<WebKitWindowProperties> windowProperties; + GRefPtr<WebKitEditorState> editorState; GRefPtr<GMainLoop> modalLoop; @@ -195,6 +210,8 @@ struct _WebKitWebViewPrivate { SnapshotResultsMap snapshotResultsMap; GRefPtr<WebKitAuthenticationRequest> authenticationRequest; + + GRefPtr<WebKitWebsiteDataManager> websiteDataManager; }; static guint signals[LAST_SIGNAL] = { 0, }; @@ -206,6 +223,87 @@ static inline WebPageProxy* getPage(WebKitWebView* webView) return webkitWebViewBaseGetPage(reinterpret_cast<WebKitWebViewBase*>(webView)); } +static void webkitWebViewSetIsLoading(WebKitWebView* webView, bool isLoading) +{ + if (webView->priv->isLoading == isLoading) + return; + + webView->priv->isLoading = isLoading; + g_object_notify(G_OBJECT(webView), "is-loading"); +} + +void webkitWebViewIsPlayingAudioChanged(WebKitWebView* webView) +{ + g_object_notify(G_OBJECT(webView), "is-playing-audio"); +} + +class PageLoadStateObserver final : public PageLoadState::Observer { +public: + PageLoadStateObserver(WebKitWebView* webView) + : m_webView(webView) + { + } + +private: + void willChangeIsLoading() override + { + g_object_freeze_notify(G_OBJECT(m_webView)); + } + void didChangeIsLoading() override + { + webkitWebViewSetIsLoading(m_webView, getPage(m_webView)->pageLoadState().isLoading()); + g_object_thaw_notify(G_OBJECT(m_webView)); + } + + void willChangeTitle() override + { + g_object_freeze_notify(G_OBJECT(m_webView)); + } + void didChangeTitle() override + { + m_webView->priv->title = getPage(m_webView)->pageLoadState().title().utf8(); + g_object_notify(G_OBJECT(m_webView), "title"); + g_object_thaw_notify(G_OBJECT(m_webView)); + } + + void willChangeActiveURL() override + { + g_object_freeze_notify(G_OBJECT(m_webView)); + } + void didChangeActiveURL() override + { + m_webView->priv->activeURI = getPage(m_webView)->pageLoadState().activeURL().utf8(); + g_object_notify(G_OBJECT(m_webView), "uri"); + g_object_thaw_notify(G_OBJECT(m_webView)); + } + + void willChangeHasOnlySecureContent() override { } + void didChangeHasOnlySecureContent() override { } + + void willChangeEstimatedProgress() override + { + g_object_freeze_notify(G_OBJECT(m_webView)); + } + void didChangeEstimatedProgress() override + { + g_object_notify(G_OBJECT(m_webView), "estimated-load-progress"); + g_object_thaw_notify(G_OBJECT(m_webView)); + } + + void willChangeCanGoBack() override { } + void didChangeCanGoBack() override { } + void willChangeCanGoForward() override { } + void didChangeCanGoForward() override { } + void willChangeNetworkRequestsInProgress() override { } + void didChangeNetworkRequestsInProgress() override { } + void willChangeCertificateInfo() override { } + void didChangeCertificateInfo() override { } + void willChangeWebProcessIsResponsive() override { } + void didChangeWebProcessIsResponsive() override { } + + WebKitWebView* m_webView; +}; + static gboolean webkitWebViewLoadFail(WebKitWebView* webView, WebKitLoadEvent, const char* failingURI, GError* error) { if (g_error_matches(error, WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED) @@ -219,19 +317,22 @@ static gboolean webkitWebViewLoadFail(WebKitWebView* webView, WebKitLoadEvent, c return TRUE; } -static GtkWidget* webkitWebViewCreate(WebKitWebView*) +static GtkWidget* webkitWebViewCreate(WebKitWebView*, WebKitNavigationAction*) { - return 0; + return nullptr; } -static GtkWidget* webkitWebViewCreateJavaScriptDialog(WebKitWebView* webView, GtkMessageType type, GtkButtonsType buttons, int defaultResponse, const char* message) +static GtkWidget* webkitWebViewCreateJavaScriptDialog(WebKitWebView* webView, GtkMessageType type, GtkButtonsType buttons, int defaultResponse, const char* primaryText, const char* secondaryText = nullptr) { GtkWidget* parent = gtk_widget_get_toplevel(GTK_WIDGET(webView)); - GtkWidget* dialog = gtk_message_dialog_new(widgetIsOnscreenToplevelWindow(parent) ? GTK_WINDOW(parent) : 0, - GTK_DIALOG_DESTROY_WITH_PARENT, type, buttons, "%s", message); - GUniquePtr<char> title(g_strdup_printf("JavaScript - %s", webkit_web_view_get_uri(webView))); + GtkWidget* dialog = gtk_message_dialog_new(widgetIsOnscreenToplevelWindow(parent) ? GTK_WINDOW(parent) : nullptr, + GTK_DIALOG_DESTROY_WITH_PARENT, type, buttons, "%s", primaryText); + if (secondaryText) + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", secondaryText); + GUniquePtr<char> title(g_strdup_printf("JavaScript - %s", getPage(webView)->pageLoadState().url().utf8().data())); gtk_window_set_title(GTK_WINDOW(dialog), title.get()); - gtk_dialog_set_default_response(GTK_DIALOG(dialog), defaultResponse); + if (buttons != GTK_BUTTONS_NONE) + gtk_dialog_set_default_response(GTK_DIALOG(dialog), defaultResponse); return dialog; } @@ -249,7 +350,7 @@ static gboolean webkitWebViewScriptDialog(WebKitWebView* webView, WebKitScriptDi dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, scriptDialog->message.data()); scriptDialog->confirmed = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK; break; - case WEBKIT_SCRIPT_DIALOG_PROMPT: + case WEBKIT_SCRIPT_DIALOG_PROMPT: { dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, scriptDialog->message.data()); GtkWidget* entry = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(entry), scriptDialog->defaultText.data()); @@ -260,13 +361,21 @@ static gboolean webkitWebViewScriptDialog(WebKitWebView* webView, WebKitScriptDi scriptDialog->text = gtk_entry_get_text(GTK_ENTRY(entry)); break; } + case WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM: + dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, GTK_RESPONSE_OK, + _("Are you sure you want to leave this page?"), scriptDialog->message.data()); + gtk_dialog_add_buttons(GTK_DIALOG(dialog), _("Stay on Page"), GTK_RESPONSE_CLOSE, _("Leave Page"), GTK_RESPONSE_OK, nullptr); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); + scriptDialog->confirmed = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK; + break; + } gtk_widget_destroy(dialog); return TRUE; } -static gboolean webkitWebViewDecidePolicy(WebKitWebView* webView, WebKitPolicyDecision* decision, WebKitPolicyDecisionType decisionType) +static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision* decision, WebKitPolicyDecisionType decisionType) { if (decisionType != WEBKIT_POLICY_DECISION_TYPE_RESPONSE) { webkit_policy_decision_use(decision); @@ -353,7 +462,7 @@ static void webkitWebViewRequestFavicon(WebKitWebView* webView) WebKitWebViewPrivate* priv = webView->priv; priv->faviconCancellable = adoptGRef(g_cancellable_new()); - WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context); + WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get()); webkit_favicon_database_get_favicon(database, priv->activeURI.data(), priv->faviconCancellable.get(), gotFaviconCallback, webView); } @@ -366,7 +475,7 @@ static void webkitWebViewUpdateFaviconURI(WebKitWebView* webView, const char* fa webkitWebViewRequestFavicon(webView); } -static void faviconChangedCallback(WebKitFaviconDatabase* database, const char* pageURI, const char* faviconURI, WebKitWebView* webView) +static void faviconChangedCallback(WebKitFaviconDatabase*, const char* pageURI, const char* faviconURI, WebKitWebView* webView) { if (webView->priv->activeURI != pageURI) return; @@ -376,16 +485,18 @@ static void faviconChangedCallback(WebKitFaviconDatabase* database, const char* static void webkitWebViewUpdateSettings(WebKitWebView* webView) { - // We keep a ref of the current settings to disconnect the signals when settings change in the group. - webView->priv->settings = webkit_web_view_get_settings(webView); + // The "settings" property is set on construction, and in that + // case webkit_web_view_set_settings() will be called *before* the + // WebPageProxy has been created so we should do an early return. + WebPageProxy* page = getPage(webView); + if (!page) + return; WebKitSettings* settings = webView->priv->settings.get(); - WebPageProxy* page = getPage(webView); + page->setPreferences(*webkitSettingsGetPreferences(settings)); page->setCanRunModal(webkit_settings_get_allow_modal_dialogs(settings)); page->setCustomUserAgent(String::fromUTF8(webkit_settings_get_user_agent(settings))); - webkitWebViewBaseUpdatePreferences(WEBKIT_WEB_VIEW_BASE(webView)); - g_signal_connect(settings, "notify::allow-modal-dialogs", G_CALLBACK(allowModalDialogsChanged), webView); g_signal_connect(settings, "notify::zoom-text-only", G_CALLBACK(zoomTextOnlyChanged), webView); g_signal_connect(settings, "notify::user-agent", G_CALLBACK(userAgentChanged), webView); @@ -399,35 +510,13 @@ static void webkitWebViewDisconnectSettingsSignalHandlers(WebKitWebView* webView g_signal_handlers_disconnect_by_func(settings, reinterpret_cast<gpointer>(userAgentChanged), webView); } -static void webkitWebViewSettingsChanged(WebKitWebViewGroup* group, GParamSpec*, WebKitWebView* webView) -{ - webkitWebViewDisconnectSettingsSignalHandlers(webView); - webkitWebViewUpdateSettings(webView); -} - -static void webkitWebViewDisconnectSettingsChangedSignalHandler(WebKitWebView* webView) -{ - WebKitWebViewPrivate* priv = webView->priv; - if (priv->settingsChangedHandlerID) - g_signal_handler_disconnect(webkit_web_view_get_group(webView), priv->settingsChangedHandlerID); - priv->settingsChangedHandlerID = 0; -} - -static void webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(WebKitWebView* webView) -{ - WebKitWebViewPrivate* priv = webView->priv; - if (priv->mainResourceResponseHandlerID) - g_signal_handler_disconnect(priv->mainResource.get(), priv->mainResourceResponseHandlerID); - priv->mainResourceResponseHandlerID = 0; -} - static void webkitWebViewWatchForChangesInFavicon(WebKitWebView* webView) { WebKitWebViewPrivate* priv = webView->priv; if (priv->faviconChangedHandlerID) return; - WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context); + WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get()); priv->faviconChangedHandlerID = g_signal_connect(database, "favicon-changed", G_CALLBACK(faviconChangedCallback), webView); } @@ -435,7 +524,7 @@ static void webkitWebViewDisconnectFaviconDatabaseSignalHandlers(WebKitWebView* { WebKitWebViewPrivate* priv = webView->priv; if (priv->faviconChangedHandlerID) - g_signal_handler_disconnect(webkit_web_context_get_favicon_database(priv->context), priv->faviconChangedHandlerID); + g_signal_handler_disconnect(webkit_web_context_get_favicon_database(priv->context.get()), priv->faviconChangedHandlerID); priv->faviconChangedHandlerID = 0; } @@ -496,14 +585,87 @@ static void webkitWebViewHandleDownloadRequest(WebKitWebViewBase* webViewBase, D webkitDownloadSetWebView(download.get(), WEBKIT_WEB_VIEW(webViewBase)); } +#if USE(LIBNOTIFY) +static const char* gNotifyNotificationID = "wk-notify-notification"; + +static void notifyNotificationClosed(NotifyNotification*, WebKitNotification* webNotification) +{ + g_object_set_data(G_OBJECT(webNotification), gNotifyNotificationID, nullptr); + webkit_notification_close(webNotification); +} + +static void notifyNotificationClicked(NotifyNotification*, char*, WebKitNotification* webNotification) +{ + webkit_notification_clicked(webNotification); +} + +static void webNotificationClosed(WebKitNotification* webNotification) +{ + NotifyNotification* notification = NOTIFY_NOTIFICATION(g_object_get_data(G_OBJECT(webNotification), gNotifyNotificationID)); + if (!notification) + return; + + notify_notification_close(notification, nullptr); + g_object_set_data(G_OBJECT(webNotification), gNotifyNotificationID, nullptr); +} +#endif // USE(LIBNOTIFY) + +static gboolean webkitWebViewShowNotification(WebKitWebView*, WebKitNotification* webNotification) +{ +#if USE(LIBNOTIFY) + if (!notify_is_initted()) + notify_init(g_get_prgname()); + + NotifyNotification* notification = NOTIFY_NOTIFICATION(g_object_get_data(G_OBJECT(webNotification), gNotifyNotificationID)); + if (!notification) { + notification = notify_notification_new(webkit_notification_get_title(webNotification), + webkit_notification_get_body(webNotification), nullptr); + + notify_notification_add_action(notification, "default", _("Acknowledge"), NOTIFY_ACTION_CALLBACK(notifyNotificationClicked), webNotification, nullptr); + + g_signal_connect_object(notification, "closed", G_CALLBACK(notifyNotificationClosed), webNotification, static_cast<GConnectFlags>(0)); + g_signal_connect(webNotification, "closed", G_CALLBACK(webNotificationClosed), nullptr); + g_object_set_data_full(G_OBJECT(webNotification), gNotifyNotificationID, notification, static_cast<GDestroyNotify>(g_object_unref)); + } else { + notify_notification_update(notification, webkit_notification_get_title(webNotification), + webkit_notification_get_body(webNotification), nullptr); + } + + notify_notification_show(notification, nullptr); + return TRUE; +#else + UNUSED_PARAM(webNotification); + return FALSE; +#endif +} + static void webkitWebViewConstructed(GObject* object) { - if (G_OBJECT_CLASS(webkit_web_view_parent_class)->constructed) - G_OBJECT_CLASS(webkit_web_view_parent_class)->constructed(object); + G_OBJECT_CLASS(webkit_web_view_parent_class)->constructed(object); WebKitWebView* webView = WEBKIT_WEB_VIEW(object); WebKitWebViewPrivate* priv = webView->priv; - webkitWebContextCreatePageForWebView(priv->context, webView, priv->group.get(), priv->relatedView); + if (priv->relatedView) { + priv->context = webkit_web_view_get_context(priv->relatedView); + priv->isEphemeral = webkit_web_view_is_ephemeral(priv->relatedView); + } else if (!priv->context) + priv->context = webkit_web_context_get_default(); + else if (!priv->isEphemeral) + priv->isEphemeral = webkit_web_context_is_ephemeral(priv->context.get()); + + if (!priv->settings) + priv->settings = adoptGRef(webkit_settings_new()); + + if (priv->isEphemeral && !webkit_web_context_is_ephemeral(priv->context.get())) { + priv->websiteDataManager = adoptGRef(webkit_website_data_manager_new_ephemeral()); + webkitWebsiteDataManagerAddProcessPool(priv->websiteDataManager.get(), webkitWebContextGetProcessPool(priv->context.get())); + } + + webkitWebContextCreatePageForWebView(priv->context.get(), webView, priv->userContentManager.get(), priv->relatedView); + + priv->loadObserver = std::make_unique<PageLoadStateObserver>(webView); + getPage(webView)->pageLoadState().addObserver(*priv->loadObserver); + // The related view is only valid during the construction. priv->relatedView = nullptr; @@ -516,12 +678,12 @@ static void webkitWebViewConstructed(GObject* object) attachContextMenuClientToView(webView); attachFormClientToView(webView); + // This needs to be after attachUIClientToView() because WebPageProxy::setUIClient() calls setCanRunModal() with true. + // See https://bugs.webkit.org/show_bug.cgi?id=135412. + webkitWebViewUpdateSettings(webView); + priv->backForwardList = adoptGRef(webkitBackForwardListCreate(&getPage(webView)->backForwardList())); priv->windowProperties = adoptGRef(webkitWindowPropertiesCreate()); - - webkitWebViewUpdateSettings(webView); - priv->settingsChangedHandlerID = - g_signal_connect(webkit_web_view_get_group(webView), "notify::settings", G_CALLBACK(webkitWebViewSettingsChanged), webView); } static void webkitWebViewSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) @@ -531,7 +693,7 @@ static void webkitWebViewSetProperty(GObject* object, guint propId, const GValue switch (propId) { case PROP_WEB_CONTEXT: { gpointer webContext = g_value_get_object(value); - webView->priv->context = webContext ? WEBKIT_WEB_CONTEXT(webContext) : webkit_web_context_get_default(); + webView->priv->context = webContext ? WEBKIT_WEB_CONTEXT(webContext) : nullptr; break; } case PROP_RELATED_VIEW: { @@ -539,16 +701,24 @@ static void webkitWebViewSetProperty(GObject* object, guint propId, const GValue webView->priv->relatedView = relatedView ? WEBKIT_WEB_VIEW(relatedView) : nullptr; break; } - case PROP_GROUP: { - gpointer group = g_value_get_object(value); - webView->priv->group = group ? WEBKIT_WEB_VIEW_GROUP(group) : 0; + case PROP_SETTINGS: { + if (gpointer settings = g_value_get_object(value)) + webkit_web_view_set_settings(webView, WEBKIT_SETTINGS(settings)); + break; + } + case PROP_USER_CONTENT_MANAGER: { + gpointer userContentManager = g_value_get_object(value); + webView->priv->userContentManager = userContentManager ? WEBKIT_USER_CONTENT_MANAGER(userContentManager) : nullptr; break; } case PROP_ZOOM_LEVEL: webkit_web_view_set_zoom_level(webView, g_value_get_double(value)); break; - case PROP_VIEW_MODE: - webkit_web_view_set_view_mode(webView, static_cast<WebKitViewMode>(g_value_get_enum(value))); + case PROP_IS_EPHEMERAL: + webView->priv->isEphemeral = g_value_get_boolean(value); + break; + case PROP_EDITABLE: + webkit_web_view_set_editable(webView, g_value_get_boolean(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); @@ -561,10 +731,13 @@ static void webkitWebViewGetProperty(GObject* object, guint propId, GValue* valu switch (propId) { case PROP_WEB_CONTEXT: - g_value_set_object(value, webView->priv->context); + g_value_set_object(value, webView->priv->context.get()); break; - case PROP_GROUP: - g_value_set_object(value, webkit_web_view_get_group(webView)); + case PROP_SETTINGS: + g_value_set_object(value, webkit_web_view_get_settings(webView)); + break; + case PROP_USER_CONTENT_MANAGER: + g_value_set_object(value, webkit_web_view_get_user_content_manager(webView)); break; case PROP_TITLE: g_value_set_string(value, webView->priv->title.data()); @@ -584,8 +757,14 @@ static void webkitWebViewGetProperty(GObject* object, guint propId, GValue* valu case PROP_IS_LOADING: g_value_set_boolean(value, webkit_web_view_is_loading(webView)); break; - case PROP_VIEW_MODE: - g_value_set_enum(value, webkit_web_view_get_view_mode(webView)); + case PROP_IS_PLAYING_AUDIO: + g_value_set_boolean(value, webkit_web_view_is_playing_audio(webView)); + break; + case PROP_IS_EPHEMERAL: + g_value_set_boolean(value, webkit_web_view_is_ephemeral(webView)); + break; + case PROP_EDITABLE: + g_value_set_boolean(value, webkit_web_view_is_editable(webView)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); @@ -596,12 +775,23 @@ static void webkitWebViewDispose(GObject* object) { WebKitWebView* webView = WEBKIT_WEB_VIEW(object); webkitWebViewCancelFaviconRequest(webView); - webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView); - webkitWebViewDisconnectSettingsChangedSignalHandler(webView); webkitWebViewDisconnectSettingsSignalHandlers(webView); webkitWebViewDisconnectFaviconDatabaseSignalHandlers(webView); - webkitWebContextWebViewDestroyed(webView->priv->context, webView); + if (webView->priv->loadObserver) { + getPage(webView)->pageLoadState().removeObserver(*webView->priv->loadObserver); + webView->priv->loadObserver.reset(); + + // We notify the context here to ensure it's called only once. Ideally we should + // call this in finalize, not dispose, but finalize is used internally and we don't + // have access to the instance pointer from the private struct destructor. + webkitWebContextWebViewDestroyed(webView->priv->context.get(), webView); + } + + if (webView->priv->websiteDataManager) { + webkitWebsiteDataManagerRemoveProcessPool(webView->priv->websiteDataManager.get(), webkitWebContextGetProcessPool(webView->priv->context.get())); + webView->priv->websiteDataManager = nullptr; + } G_OBJECT_CLASS(webkit_web_view_parent_class)->dispose(object); } @@ -631,6 +821,7 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) webViewClass->permission_request = webkitWebViewPermissionRequest; webViewClass->run_file_chooser = webkitWebViewRunFileChooser; webViewClass->authenticate = webkitWebViewAuthenticate; + webViewClass->show_notification = webkitWebViewShowNotification; /** * WebKitWebView:web-context: @@ -664,18 +855,37 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) static_cast<GParamFlags>(WEBKIT_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY))); /** - * WebKitWebView:group: + * WebKitWebView:settings: + * + * The #WebKitSettings of the view. * - * The #WebKitWebViewGroup of the view. + * Since: 2.6 */ g_object_class_install_property( gObjectClass, - PROP_GROUP, + PROP_SETTINGS, g_param_spec_object( - "group", - _("WebView Group"), - _("The WebKitWebViewGroup of the view"), - WEBKIT_TYPE_WEB_VIEW_GROUP, + "settings", + _("WebView settings"), + _("The WebKitSettings of the view"), + WEBKIT_TYPE_SETTINGS, + static_cast<GParamFlags>(WEBKIT_PARAM_WRITABLE | G_PARAM_CONSTRUCT))); + + /** + * WebKitWebView:user-content-manager: + * + * The #WebKitUserContentManager of the view. + * + * Since: 2.6 + */ + g_object_class_install_property( + gObjectClass, + PROP_USER_CONTENT_MANAGER, + g_param_spec_object( + "user-content-manager", + _("WebView user content manager"), + _("The WebKitUserContentManager of the view"), + WEBKIT_TYPE_USER_CONTENT_MANAGER, static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); /** @@ -742,13 +952,15 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * The zoom level of the #WebKitWebView content. * See webkit_web_view_set_zoom_level() for more details. */ - g_object_class_install_property(gObjectClass, - PROP_ZOOM_LEVEL, - g_param_spec_double("zoom-level", - "Zoom level", - _("The zoom level of the view content"), - 0, G_MAXDOUBLE, 1, - WEBKIT_PARAM_READWRITE)); + g_object_class_install_property( + gObjectClass, + PROP_ZOOM_LEVEL, + g_param_spec_double( + "zoom-level", + _("Zoom level"), + _("The zoom level of the view content"), + 0, G_MAXDOUBLE, 1, + WEBKIT_PARAM_READWRITE)); /** * WebKitWebView:is-loading: @@ -760,28 +972,76 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * When the load operation finishes the property is set to %FALSE before * #WebKitWebView::load-changed is emitted with %WEBKIT_LOAD_FINISHED. */ - g_object_class_install_property(gObjectClass, - PROP_IS_LOADING, - g_param_spec_boolean("is-loading", - "Is Loading", - _("Whether the view is loading a page"), - FALSE, - WEBKIT_PARAM_READABLE)); + g_object_class_install_property( + gObjectClass, + PROP_IS_LOADING, + g_param_spec_boolean( + "is-loading", + _("Is Loading"), + _("Whether the view is loading a page"), + FALSE, + WEBKIT_PARAM_READABLE)); /** - * WebKitWebView:view-mode: + * WebKitWebView:is-playing-audio: + * + * Whether the #WebKitWebView is currently playing audio from a page. + * This property becomes %TRUE as soon as web content starts playing any + * kind of audio. When a page is no longer playing any kind of sound, + * the property is set back to %FALSE. * - * The #WebKitViewMode that is used to display the contents of a #WebKitWebView. - * See also webkit_web_view_set_view_mode(). + * Since: 2.8 */ - g_object_class_install_property(gObjectClass, - PROP_VIEW_MODE, - g_param_spec_enum("view-mode", - "View Mode", - _("The view mode to display the web view contents"), - WEBKIT_TYPE_VIEW_MODE, - WEBKIT_VIEW_MODE_WEB, - WEBKIT_PARAM_READWRITE)); + g_object_class_install_property( + gObjectClass, + PROP_IS_PLAYING_AUDIO, + g_param_spec_boolean( + "is-playing-audio", + "Is Playing Audio", + _("Whether the view is playing audio"), + FALSE, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitWebView:is-ephemeral: + * + * Whether the #WebKitWebView is ephemeral. An ephemeral web view never writes + * website data to the client storage, no matter what #WebKitWebsiteDataManager + * its context is using. This is normally used to implement private browsing mode. + * This is a %G_PARAM_CONSTRUCT_ONLY property, so you have to create a ephemeral + * #WebKitWebView and it can't be changed. Note that all #WebKitWebView<!-- -->s + * created with an ephemeral #WebKitWebContext will be ephemeral automatically. + * See also webkit_web_context_new_ephemeral(). + * + * Since: 2.16 + */ + g_object_class_install_property( + gObjectClass, + PROP_IS_EPHEMERAL, + g_param_spec_boolean( + "is-ephemeral", + "Is Ephemeral", + _("Whether the web view is ephemeral"), + FALSE, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebView:editable: + * + * Whether the pages loaded inside #WebKitWebView are editable. For more + * information see webkit_web_view_set_editable(). + * + * Since: 2.8 + */ + g_object_class_install_property( + gObjectClass, + PROP_EDITABLE, + g_param_spec_boolean( + "editable", + _("Editable"), + _("Whether the content can be modified by the user."), + FALSE, + WEBKIT_PARAM_READWRITE)); /** * WebKitWebView::load-changed: @@ -865,30 +1125,31 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * %FALSE to propagate the event further. */ signals[LOAD_FAILED] = - g_signal_new("load-failed", - G_TYPE_FROM_CLASS(webViewClass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitWebViewClass, load_failed), - g_signal_accumulator_true_handled, 0, - webkit_marshal_BOOLEAN__ENUM_STRING_POINTER, - G_TYPE_BOOLEAN, 3, - WEBKIT_TYPE_LOAD_EVENT, - G_TYPE_STRING, - G_TYPE_POINTER); + g_signal_new( + "load-failed", + G_TYPE_FROM_CLASS(webViewClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitWebViewClass, load_failed), + g_signal_accumulator_true_handled, 0, + g_cclosure_marshal_generic, + G_TYPE_BOOLEAN, 3, + WEBKIT_TYPE_LOAD_EVENT, + G_TYPE_STRING, + G_TYPE_ERROR | G_SIGNAL_TYPE_STATIC_SCOPE); /** * WebKitWebView::load-failed-with-tls-errors: * @web_view: the #WebKitWebView on which the signal is emitted - * @info: a #WebKitCertificateInfo - * @host: the host on which the error occurred + * @failing_uri: the URI that failed to load + * @certificate: a #GTlsCertificate + * @errors: a #GTlsCertificateFlags with the verification status of @certificate * - * Emitted when a TLS error occurs during a load operation. The @info - * object contains information about the error such as the #GTlsCertificate - * and the #GTlsCertificateFlags. To allow an exception for this certificate - * and this host use webkit_web_context_allow_tls_certificate_for_host(). + * Emitted when a TLS error occurs during a load operation. + * To allow an exception for this @certificate + * and the host of @failing_uri use webkit_web_context_allow_tls_certificate_for_host(). * - * To handle this signal asynchronously you should copy the #WebKitCertificateInfo - * with webkit_certificate_info_copy() and return %TRUE. + * To handle this signal asynchronously you should call g_object_ref() on @certificate + * and return %TRUE. * * If %FALSE is returned, #WebKitWebView::load-failed will be emitted. The load * will finish regardless of the returned value. @@ -896,7 +1157,7 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * Returns: %TRUE to stop other handlers from being invoked for the event. * %FALSE to propagate the event further. * - * Since: 2.4 + * Since: 2.6 */ signals[LOAD_FAILED_WITH_TLS_ERRORS] = g_signal_new("load-failed-with-tls-errors", @@ -904,22 +1165,27 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(WebKitWebViewClass, load_failed_with_tls_errors), g_signal_accumulator_true_handled, 0 /* accumulator data */, - webkit_marshal_BOOLEAN__BOXED_STRING, - G_TYPE_BOOLEAN, 2, /* number of parameters */ - WEBKIT_TYPE_CERTIFICATE_INFO | G_SIGNAL_TYPE_STATIC_SCOPE, - G_TYPE_STRING); + g_cclosure_marshal_generic, + G_TYPE_BOOLEAN, 3, + G_TYPE_STRING, + G_TYPE_TLS_CERTIFICATE, + G_TYPE_TLS_CERTIFICATE_FLAGS); /** * WebKitWebView::create: * @web_view: the #WebKitWebView on which the signal is emitted + * @navigation_action: a #WebKitNavigationAction * * Emitted when the creation of a new #WebKitWebView is requested. * If this signal is handled the signal handler should return the * newly created #WebKitWebView. * + * The #WebKitNavigationAction parameter contains information about the + * navigation action that triggered this signal. + * * When using %WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES * process model, the new #WebKitWebView should be related to - * @web_view to share the same web process, see webkit_web_view_new_with_related_view + * @web_view to share the same web process, see webkit_web_view_new_with_related_view() * for more details. * * The new #WebKitWebView should not be displayed to the user @@ -928,14 +1194,15 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * Returns: (transfer full): a newly allocated #WebKitWebView widget * or %NULL to propagate the event further. */ - signals[CREATE] = - g_signal_new("create", - G_TYPE_FROM_CLASS(webViewClass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitWebViewClass, create), - webkitWebViewAccumulatorObjectHandled, 0, - webkit_marshal_OBJECT__VOID, - GTK_TYPE_WIDGET, 0); + signals[CREATE] = g_signal_new( + "create", + G_TYPE_FROM_CLASS(webViewClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitWebViewClass, create), + webkitWebViewAccumulatorObjectHandled, 0, + g_cclosure_marshal_generic, + GTK_TYPE_WIDGET, 1, + WEBKIT_TYPE_NAVIGATION_ACTION | G_SIGNAL_TYPE_STATIC_SCOPE); /** * WebKitWebView::ready-to-show: @@ -980,10 +1247,11 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) /** * WebKitWebView::close: - * @webView: the #WebKitWebView on which the signal is emitted + * @web_view: the #WebKitWebView on which the signal is emitted * * Emitted when closing a #WebKitWebView is requested. This occurs when a - * call is made from JavaScript's <function>window.close</function> function. + * call is made from JavaScript's <function>window.close</function> function or + * after trying to close the @web_view with webkit_web_view_try_close(). * It is the owner's responsibility to handle this signal to hide or * destroy the #WebKitWebView, if necessary. */ @@ -1002,7 +1270,8 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * @dialog: the #WebKitScriptDialog to show * * Emitted when JavaScript code calls <function>window.alert</function>, - * <function>window.confirm</function> or <function>window.prompt</function>. + * <function>window.confirm</function> or <function>window.prompt</function>, + * or when <function>onbeforeunload</function> event is fired. * The @dialog parameter should be used to build the dialog. * If the signal is not handled a different dialog will be built and shown depending * on the dialog type: @@ -1017,6 +1286,9 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * %WEBKIT_SCRIPT_DIALOG_PROMPT: message dialog with OK and Cancel buttons and * a text entry with the default text. * </para></listitem> + * <listitem><para> + * %WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM: message dialog with Stay and Leave buttons. + * </para></listitem> * </itemizedlist> * * Returns: %TRUE to stop other handlers from being invoked for the event. @@ -1140,9 +1412,10 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * request has not been handled, webkit_permission_request_deny() * will be the default action. * - * By default, if the signal is not handled, - * webkit_permission_request_deny() will be called over the - * #WebKitPermissionRequest. + * If the signal is not handled, the @request will be completed automatically + * by the specific #WebKitPermissionRequest that could allow or deny it. Check the + * documentation of classes implementing #WebKitPermissionRequest interface to know + * their default action. * * Returns: %TRUE to stop other handlers from being invoked for the event. * %FALSE to propagate the event further. @@ -1315,8 +1588,8 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * @event: the #GdkEvent that triggered the context menu * @hit_test_result: a #WebKitHitTestResult * - * Emmited when a context menu is about to be displayed to give the application - * a chance to customize the proposed menu, prevent the menu from being displayed + * Emitted when a context menu is about to be displayed to give the application + * a chance to customize the proposed menu, prevent the menu from being displayed, * or build its own context menu. * <itemizedlist> * <listitem><para> @@ -1343,6 +1616,22 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * </para></listitem> * </itemizedlist> * + * The @event is expected to be one of the following types: + * <itemizedlist> + * <listitem><para> + * a #GdkEventButton of type %GDK_BUTTON_PRESS when the context menu + * was triggered with mouse. + * </para></listitem> + * <listitem><para> + * a #GdkEventKey of type %GDK_KEY_PRESS if the keyboard was used to show + * the menu. + * </para></listitem> + * <listitem><para> + * a generic #GdkEvent of type %GDK_NOTHING when the #GtkWidget:popup-menu + * signal was used to show the context menu. + * </para></listitem> + * </itemizedlist> + * * If the signal handler returns %FALSE the context menu represented by @context_menu * will be shown, if it return %TRUE the context menu will not be shown. * @@ -1482,21 +1771,66 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) webkit_marshal_BOOLEAN__OBJECT, G_TYPE_BOOLEAN, 1, /* number of parameters */ WEBKIT_TYPE_AUTHENTICATION_REQUEST); -} - -static void webkitWebViewSetIsLoading(WebKitWebView* webView, bool isLoading) -{ - if (webView->priv->isLoading == isLoading) - return; - webView->priv->isLoading = isLoading; - g_object_freeze_notify(G_OBJECT(webView)); - g_object_notify(G_OBJECT(webView), "is-loading"); + /** + * WebKitWebView::show-notification: + * @web_view: the #WebKitWebView + * @notification: a #WebKitNotification + * + * This signal is emitted when a notification should be presented to the + * user. The @notification is kept alive until either: 1) the web page cancels it + * or 2) a navigation happens. + * + * The default handler will emit a notification using libnotify, if built with + * support for it. + * + * Returns: %TRUE to stop other handlers from being invoked. %FALSE otherwise. + * + * Since: 2.8 + */ + signals[SHOW_NOTIFICATION] = + g_signal_new("show-notification", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitWebViewClass, show_notification), + g_signal_accumulator_true_handled, nullptr /* accumulator data */, + webkit_marshal_BOOLEAN__OBJECT, + G_TYPE_BOOLEAN, 1, + WEBKIT_TYPE_NOTIFICATION); - // Update the URI if a new load has started. - if (webView->priv->isLoading) - webkitWebViewUpdateURI(webView); - g_object_thaw_notify(G_OBJECT(webView)); + /** + * WebKitWebView::run-color-chooser: + * @web_view: the #WebKitWebView on which the signal is emitted + * @request: a #WebKitColorChooserRequest + * + * This signal is emitted when the user interacts with a <input + * type='color' /> HTML element, requesting from WebKit to show + * a dialog to select a color. To let the application know the details of + * the color chooser, as well as to allow the client application to either + * cancel the request or perform an actual color selection, the signal will + * pass an instance of the #WebKitColorChooserRequest in the @request + * argument. + * + * It is possible to handle this request asynchronously by increasing the + * reference count of the request. + * + * The default signal handler will asynchronously run a regular + * #GtkColorChooser for the user to interact with. + * + * Returns: %TRUE to stop other handlers from being invoked for the event. + * %FALSE to propagate the event further. + * + * Since: 2.8 + */ + signals[RUN_COLOR_CHOOSER] = + g_signal_new("run-color-chooser", + G_TYPE_FROM_CLASS(webViewClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitWebViewClass, run_color_chooser), + g_signal_accumulator_true_handled, nullptr, + webkit_marshal_BOOLEAN__OBJECT, + G_TYPE_BOOLEAN, 1, + WEBKIT_TYPE_COLOR_CHOOSER_REQUEST); } static void webkitWebViewCancelAuthenticationRequest(WebKitWebView* webView) @@ -1508,68 +1842,35 @@ static void webkitWebViewCancelAuthenticationRequest(WebKitWebView* webView) webView->priv->authenticationRequest.clear(); } -static void webkitWebViewEmitLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent) -{ - if (loadEvent == WEBKIT_LOAD_STARTED) { - webkitWebViewSetIsLoading(webView, true); - webkitWebViewWatchForChangesInFavicon(webView); - webkitWebViewCancelAuthenticationRequest(webView); - } else if (loadEvent == WEBKIT_LOAD_FINISHED) { - webkitWebViewSetIsLoading(webView, false); - webkitWebViewCancelAuthenticationRequest(webView); - webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView); - } else - webkitWebViewUpdateURI(webView); - g_signal_emit(webView, signals[LOAD_CHANGED], 0, loadEvent); -} - -static void webkitWebViewEmitDelayedLoadEvents(WebKitWebView* webView) -{ - WebKitWebViewPrivate* priv = webView->priv; - if (!priv->waitingForMainResource) - return; - ASSERT(priv->lastDelayedEvent == WEBKIT_LOAD_COMMITTED || priv->lastDelayedEvent == WEBKIT_LOAD_FINISHED); - - if (priv->lastDelayedEvent == WEBKIT_LOAD_FINISHED) - webkitWebViewEmitLoadChanged(webView, WEBKIT_LOAD_COMMITTED); - webkitWebViewEmitLoadChanged(webView, priv->lastDelayedEvent); - priv->waitingForMainResource = false; -} - void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent) { WebKitWebViewPrivate* priv = webView->priv; - if (loadEvent == WEBKIT_LOAD_STARTED) { - // Finish a possible previous load waiting for main resource. - webkitWebViewEmitDelayedLoadEvents(webView); - + switch (loadEvent) { + case WEBKIT_LOAD_STARTED: webkitWebViewCancelFaviconRequest(webView); + webkitWebViewWatchForChangesInFavicon(webView); + webkitWebViewCancelAuthenticationRequest(webView); priv->loadingResourcesMap.clear(); - priv->mainResource = 0; - priv->waitingForMainResource = false; - } else if (loadEvent == WEBKIT_LOAD_COMMITTED) { - WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context); + priv->mainResource = nullptr; + break; + case WEBKIT_LOAD_COMMITTED: { + WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get()); GUniquePtr<char> faviconURI(webkit_favicon_database_get_favicon_uri(database, priv->activeURI.data())); webkitWebViewUpdateFaviconURI(webView, faviconURI.get()); - - if (!priv->mainResource) { - // When a page is loaded from the history cache, the main resource load callbacks - // are called when the main frame load is finished. We want to make sure there's a - // main resource available when load has been committed, so we delay the emission of - // load-changed signal until main resource object has been created. - priv->waitingForMainResource = true; - } + break; + } + case WEBKIT_LOAD_FINISHED: + webkitWebViewCancelAuthenticationRequest(webView); + break; + default: + break; } - if (priv->waitingForMainResource) - priv->lastDelayedEvent = loadEvent; - else - webkitWebViewEmitLoadChanged(webView, loadEvent); + g_signal_emit(webView, signals[LOAD_CHANGED], 0, loadEvent); } void webkitWebViewLoadFailed(WebKitWebView* webView, WebKitLoadEvent loadEvent, const char* failingURI, GError *error) { - webkitWebViewSetIsLoading(webView, false); webkitWebViewCancelAuthenticationRequest(webView); gboolean returnValue; @@ -1579,15 +1880,12 @@ void webkitWebViewLoadFailed(WebKitWebView* webView, WebKitLoadEvent loadEvent, void webkitWebViewLoadFailedWithTLSErrors(WebKitWebView* webView, const char* failingURI, GError* error, GTlsCertificateFlags tlsErrors, GTlsCertificate* certificate) { - webkitWebViewSetIsLoading(webView, false); webkitWebViewCancelAuthenticationRequest(webView); - WebKitTLSErrorsPolicy tlsErrorsPolicy = webkit_web_context_get_tls_errors_policy(webView->priv->context); + WebKitTLSErrorsPolicy tlsErrorsPolicy = webkit_web_context_get_tls_errors_policy(webView->priv->context.get()); if (tlsErrorsPolicy == WEBKIT_TLS_ERRORS_POLICY_FAIL) { - GUniquePtr<SoupURI> soupURI(soup_uri_new(failingURI)); - WebKitCertificateInfo info(certificate, tlsErrors); gboolean returnValue; - g_signal_emit(webView, signals[LOAD_FAILED_WITH_TLS_ERRORS], 0, &info, soupURI->host, &returnValue); + g_signal_emit(webView, signals[LOAD_FAILED_WITH_TLS_ERRORS], 0, failingURI, certificate, tlsErrors, &returnValue); if (!returnValue) g_signal_emit(webView, signals[LOAD_FAILED], 0, WEBKIT_LOAD_STARTED, failingURI, error, &returnValue); } @@ -1595,46 +1893,17 @@ void webkitWebViewLoadFailedWithTLSErrors(WebKitWebView* webView, const char* fa g_signal_emit(webView, signals[LOAD_CHANGED], 0, WEBKIT_LOAD_FINISHED); } -void webkitWebViewSetTitle(WebKitWebView* webView, const CString& title) -{ - WebKitWebViewPrivate* priv = webView->priv; - if (priv->title == title) - return; - - priv->title = title; - g_object_notify(G_OBJECT(webView), "title"); -} - -void webkitWebViewSetEstimatedLoadProgress(WebKitWebView* webView, double estimatedLoadProgress) -{ - if (webView->priv->estimatedLoadProgress == estimatedLoadProgress) - return; - - webView->priv->estimatedLoadProgress = estimatedLoadProgress; - g_object_notify(G_OBJECT(webView), "estimated-load-progress"); -} - -void webkitWebViewUpdateURI(WebKitWebView* webView) -{ - CString activeURI = getPage(webView)->pageLoadState().activeURL().utf8(); - if (webView->priv->activeURI == activeURI) - return; - - webView->priv->activeURI = activeURI; - g_object_notify(G_OBJECT(webView), "uri"); -} - -WebPageProxy* webkitWebViewCreateNewPage(WebKitWebView* webView, ImmutableDictionary* windowFeatures) +WebPageProxy* webkitWebViewCreateNewPage(WebKitWebView* webView, const WindowFeatures& windowFeatures, WebKitNavigationAction* navigationAction) { WebKitWebView* newWebView; - g_signal_emit(webView, signals[CREATE], 0, &newWebView); + g_signal_emit(webView, signals[CREATE], 0, navigationAction, &newWebView); if (!newWebView) return 0; webkitWindowPropertiesUpdateFromWebWindowFeatures(newWebView->priv->windowProperties.get(), windowFeatures); RefPtr<WebPageProxy> newPage = getPage(newWebView); - return newPage.release().leakRef(); + return newPage.leakRef(); } void webkitWebViewReadyToShowPage(WebKitWebView* webView) @@ -1647,9 +1916,14 @@ void webkitWebViewRunAsModal(WebKitWebView* webView) g_signal_emit(webView, signals[RUN_AS_MODAL], 0, NULL); webView->priv->modalLoop = adoptGRef(g_main_loop_new(0, FALSE)); + +// This is to suppress warnings about gdk_threads_leave and gdk_threads_enter. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" gdk_threads_leave(); g_main_loop_run(webView->priv->modalLoop.get()); gdk_threads_enter(); +#pragma GCC diagnostic pop } void webkitWebViewClosePage(WebKitWebView* webView) @@ -1680,6 +1954,14 @@ CString webkitWebViewRunJavaScriptPrompt(WebKitWebView* webView, const CString& return dialog.text; } +bool webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView* webView, const CString& message) +{ + WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM, message); + gboolean returnValue; + g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue); + return dialog.confirmed; +} + void webkitWebViewMakePolicyDecision(WebKitWebView* webView, WebKitPolicyDecisionType type, WebKitPolicyDecision* decision) { gboolean returnValue; @@ -1692,9 +1974,9 @@ void webkitWebViewMakePermissionRequest(WebKitWebView* webView, WebKitPermission g_signal_emit(webView, signals[PERMISSION_REQUEST], 0, request, &returnValue); } -void webkitWebViewMouseTargetChanged(WebKitWebView* webView, WebHitTestResult* hitTestResult, unsigned modifiers) +void webkitWebViewMouseTargetChanged(WebKitWebView* webView, const WebHitTestResultData& hitTestResult, unsigned modifiers) { - webkitWebViewBaseSetTooltipArea(WEBKIT_WEB_VIEW_BASE(webView), hitTestResult->elementBoundingBox()); + webkitWebViewBaseSetTooltipArea(WEBKIT_WEB_VIEW_BASE(webView), hitTestResult.elementBoundingBox); WebKitWebViewPrivate* priv = webView->priv; if (priv->mouseTargetHitTestResult @@ -1709,7 +1991,7 @@ void webkitWebViewMouseTargetChanged(WebKitWebView* webView, WebHitTestResult* h void webkitWebViewPrintFrame(WebKitWebView* webView, WebFrameProxy* frame) { - GRefPtr<WebKitPrintOperation> printOperation = adoptGRef(webkit_print_operation_new(webView)); + auto printOperation = adoptGRef(webkit_print_operation_new(webView)); webkitPrintOperationSetPrintMode(printOperation.get(), PrintInfo::PrintModeSync); gboolean returnValue; g_signal_emit(webView, signals[PRINT], 0, printOperation.get(), &returnValue); @@ -1722,32 +2004,13 @@ void webkitWebViewPrintFrame(WebKitWebView* webView, WebFrameProxy* frame) g_signal_connect(printOperation.leakRef(), "finished", G_CALLBACK(g_object_unref), 0); } -static void mainResourceResponseChangedCallback(WebKitWebResource*, GParamSpec*, WebKitWebView* webView) -{ - webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView); - webkitWebViewEmitDelayedLoadEvents(webView); -} - -static void waitForMainResourceResponseIfWaitingForResource(WebKitWebView* webView) -{ - WebKitWebViewPrivate* priv = webView->priv; - if (!priv->waitingForMainResource) - return; - - webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView); - priv->mainResourceResponseHandlerID = - g_signal_connect(priv->mainResource.get(), "notify::response", G_CALLBACK(mainResourceResponseChangedCallback), webView); -} - void webkitWebViewResourceLoadStarted(WebKitWebView* webView, WebFrameProxy* frame, uint64_t resourceIdentifier, WebKitURIRequest* request) { WebKitWebViewPrivate* priv = webView->priv; bool isMainResource = frame->isMainFrame() && !priv->mainResource; WebKitWebResource* resource = webkitWebResourceCreate(frame, request, isMainResource); - if (isMainResource) { + if (isMainResource) priv->mainResource = resource; - waitForMainResourceResponseIfWaitingForResource(webView); - } priv->loadingResourcesMap.set(resourceIdentifier, adoptGRef(resource)); g_signal_emit(webView, signals[RESOURCE_LOAD_STARTED], 0, resource, request); } @@ -1785,76 +2048,29 @@ void webkitWebViewRunFileChooserRequest(WebKitWebView* webView, WebKitFileChoose g_signal_emit(webView, signals[RUN_FILE_CHOOSER], 0, request, &returnValue); } -static bool webkitWebViewShouldShowInputMethodsMenu(WebKitWebView* webView) -{ - GtkSettings* settings = gtk_widget_get_settings(GTK_WIDGET(webView)); - if (!settings) - return true; - - gboolean showInputMethodMenu; - g_object_get(settings, "gtk-show-input-method-menu", &showInputMethodMenu, NULL); - return showInputMethodMenu; -} - -static int getUnicodeMenuItemPosition(WebKitContextMenu* contextMenu) -{ - GList* items = webkit_context_menu_get_items(contextMenu); - GList* iter; - int i = 0; - for (iter = items, i = 0; iter; iter = g_list_next(iter), ++i) { - WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(iter->data); - - if (webkit_context_menu_item_is_separator(item)) - continue; - if (webkit_context_menu_item_get_stock_action(item) == WEBKIT_CONTEXT_MENU_ACTION_UNICODE) - return i; - } - return -1; -} - -static void webkitWebViewCreateAndAppendInputMethodsMenuItem(WebKitWebView* webView, WebKitContextMenu* contextMenu) -{ - if (!webkitWebViewShouldShowInputMethodsMenu(webView)) - return; - - // Place the im context menu item right before the unicode menu item - // if it's present. - int unicodeMenuItemPosition = getUnicodeMenuItemPosition(contextMenu); - if (unicodeMenuItemPosition == -1) - webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator()); - - GtkIMContext* imContext = webkitWebViewBaseGetIMContext(WEBKIT_WEB_VIEW_BASE(webView)); - GtkMenu* imContextMenu = GTK_MENU(gtk_menu_new()); - gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(imContext), GTK_MENU_SHELL(imContextMenu)); - WebKitContextMenuItem* menuItem = webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_INPUT_METHODS); - webkitContextMenuItemSetSubMenuFromGtkMenu(menuItem, imContextMenu); - webkit_context_menu_insert(contextMenu, menuItem, unicodeMenuItemPosition); -} - static void contextMenuDismissed(GtkMenuShell*, WebKitWebView* webView) { g_signal_emit(webView, signals[CONTEXT_MENU_DISMISSED], 0, NULL); } -void webkitWebViewPopulateContextMenu(WebKitWebView* webView, API::Array* proposedMenu, WebHitTestResult* webHitTestResult) +void webkitWebViewPopulateContextMenu(WebKitWebView* webView, const Vector<WebContextMenuItemData>& proposedMenu, const WebHitTestResultData& hitTestResultData, GVariant* userData) { WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(webView); WebContextMenuProxyGtk* contextMenuProxy = webkitWebViewBaseGetActiveContextMenuProxy(webViewBase); ASSERT(contextMenuProxy); GRefPtr<WebKitContextMenu> contextMenu = adoptGRef(webkitContextMenuCreate(proposedMenu)); - if (webHitTestResult->isContentEditable()) - webkitWebViewCreateAndAppendInputMethodsMenuItem(webView, contextMenu.get()); + if (userData) + webkit_context_menu_set_user_data(WEBKIT_CONTEXT_MENU(contextMenu.get()), userData); - GRefPtr<WebKitHitTestResult> hitTestResult = adoptGRef(webkitHitTestResultCreate(webHitTestResult)); + GRefPtr<WebKitHitTestResult> hitTestResult = adoptGRef(webkitHitTestResultCreate(hitTestResultData)); GUniquePtr<GdkEvent> contextMenuEvent(webkitWebViewBaseTakeContextMenuEvent(webViewBase)); - gboolean returnValue; g_signal_emit(webView, signals[CONTEXT_MENU], 0, contextMenu.get(), contextMenuEvent.get(), hitTestResult.get(), &returnValue); if (returnValue) return; - Vector<ContextMenuItem> contextMenuItems; + Vector<WebContextMenuItemGtk> contextMenuItems; webkitContextMenuPopulate(contextMenu.get(), contextMenuItems); contextMenuProxy->populate(contextMenuItems); @@ -1871,7 +2087,9 @@ void webkitWebViewSubmitFormRequest(WebKitWebView* webView, WebKitFormSubmission void webkitWebViewHandleAuthenticationChallenge(WebKitWebView* webView, AuthenticationChallengeProxy* authenticationChallenge) { - gboolean privateBrowsingEnabled = webkit_settings_get_enable_private_browsing(webkit_web_view_get_settings(webView)); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + gboolean privateBrowsingEnabled = webView->priv->isEphemeral || webkit_settings_get_enable_private_browsing(webView->priv->settings.get()); + G_GNUC_END_IGNORE_DEPRECATIONS; webView->priv->authenticationRequest = adoptGRef(webkitAuthenticationRequestCreate(authenticationChallenge, privateBrowsingEnabled)); gboolean returnValue; g_signal_emit(webView, signals[AUTHENTICATE], 0, webView->priv->authenticationRequest.get(), &returnValue); @@ -1882,12 +2100,51 @@ void webkitWebViewInsecureContentDetected(WebKitWebView* webView, WebKitInsecure g_signal_emit(webView, signals[INSECURE_CONTENT_DETECTED], 0, type); } +bool webkitWebViewEmitShowNotification(WebKitWebView* webView, WebKitNotification* webNotification) +{ + gboolean handled; + g_signal_emit(webView, signals[SHOW_NOTIFICATION], 0, webNotification, &handled); + return handled; +} + +bool webkitWebViewEmitRunColorChooser(WebKitWebView* webView, WebKitColorChooserRequest* request) +{ + gboolean handled; + g_signal_emit(webView, signals[RUN_COLOR_CHOOSER], 0, request, &handled); + return handled; +} + +void webkitWebViewSelectionDidChange(WebKitWebView* webView) +{ + if (!webView->priv->editorState) + return; + + webkitEditorStateChanged(webView->priv->editorState.get(), getPage(webView)->editorState()); +} + +void webkitWebViewRequestInstallMissingMediaPlugins(WebKitWebView* webView, InstallMissingMediaPluginsPermissionRequest& request) +{ +#if ENABLE(VIDEO) + GRefPtr<WebKitInstallMissingMediaPluginsPermissionRequest> installMediaPluginsPermissionRequest = adoptGRef(webkitInstallMissingMediaPluginsPermissionRequestCreate(request)); + webkitWebViewMakePermissionRequest(webView, WEBKIT_PERMISSION_REQUEST(installMediaPluginsPermissionRequest.get())); +#else + ASSERT_NOT_REACHED(); +#endif +} + +WebKitWebsiteDataManager* webkitWebViewGetWebsiteDataManager(WebKitWebView* webView) +{ + return webView->priv->websiteDataManager.get(); +} + /** * webkit_web_view_new: * - * Creates a new #WebKitWebView with the default #WebKitWebContext and the - * default #WebKitWebViewGroup. - * See also webkit_web_view_new_with_context() and webkit_web_view_new_with_group(). + * Creates a new #WebKitWebView with the default #WebKitWebContext and + * no #WebKitUserContentManager associated with it. + * See also webkit_web_view_new_with_context(), + * webkit_web_view_new_with_user_content_manager(), and + * webkit_web_view_new_with_settings(). * * Returns: The newly created #WebKitWebView widget */ @@ -1900,9 +2157,10 @@ GtkWidget* webkit_web_view_new() * webkit_web_view_new_with_context: * @context: the #WebKitWebContext to be used by the #WebKitWebView * - * Creates a new #WebKitWebView with the given #WebKitWebContext and the - * default #WebKitWebViewGroup. - * See also webkit_web_view_new_with_group(). + * Creates a new #WebKitWebView with the given #WebKitWebContext and + * no #WebKitUserContentManager associated with it. + * See also webkit_web_view_new_with_user_content_manager() and + * webkit_web_view_new_with_settings(). * * Returns: The newly created #WebKitWebView widget */ @@ -1910,7 +2168,10 @@ GtkWidget* webkit_web_view_new_with_context(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); - return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, "web-context", context, NULL)); + return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, + "is-ephemeral", webkit_web_context_is_ephemeral(context), + "web-context", context, + nullptr)); } /** @@ -1925,6 +2186,9 @@ GtkWidget* webkit_web_view_new_with_context(WebKitWebContext* context) * You can also use this method to implement other process models based on %WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES, * like for example, sharing the same web process for all the views in the same security domain. * + * The newly created #WebKitWebView will also have the same #WebKitUserContentManager + * and #WebKitSettings as @web_view. + * * Returns: (transfer full): The newly created #WebKitWebView widget * * Since: 2.4 @@ -1933,24 +2197,48 @@ GtkWidget* webkit_web_view_new_with_related_view(WebKitWebView* webView) { g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr); - return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, "related-view", webView, nullptr)); + return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, + "user-content-manager", webView->priv->userContentManager.get(), + "settings", webView->priv->settings.get(), + "related-view", webView, + nullptr)); } /** - * webkit_web_view_new_with_group: - * @group: a #WebKitWebViewGroup + * webkit_web_view_new_with_settings: + * @settings: a #WebKitSettings * - * Creates a new #WebKitWebView with the given #WebKitWebViewGroup. - * The view will be part of @group and it will be affected by the - * group properties like the settings. + * Creates a new #WebKitWebView with the given #WebKitSettings. + * See also webkit_web_view_new_with_context(), and + * webkit_web_view_new_with_user_content_manager(). * * Returns: The newly created #WebKitWebView widget + * + * Since: 2.6 */ -GtkWidget* webkit_web_view_new_with_group(WebKitWebViewGroup* group) +GtkWidget* webkit_web_view_new_with_settings(WebKitSettings* settings) { - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group), 0); + g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), nullptr); + return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, "settings", settings, nullptr)); +} - return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, "group", group, NULL)); +/** + * webkit_web_view_new_with_user_content_manager: + * @user_content_manager: a #WebKitUserContentManager. + * + * Creates a new #WebKitWebView with the given #WebKitUserContentManager. + * The content loaded in the view may be affected by the content injected + * in the view by the user content manager. + * + * Returns: The newly created #WebKitWebView widget + * + * Since: 2.6 + */ +GtkWidget* webkit_web_view_new_with_user_content_manager(WebKitUserContentManager* userContentManager) +{ + g_return_val_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(userContentManager), nullptr); + + return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, "user-content-manager", userContentManager, nullptr)); } /** @@ -1965,25 +2253,86 @@ WebKitWebContext* webkit_web_view_get_context(WebKitWebView *webView) { g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); - return webView->priv->context; + return webView->priv->context.get(); } /** - * webkit_web_view_get_group: + * webkit_web_view_get_user_content_manager: * @web_view: a #WebKitWebView * - * Gets the group @web_view belongs to. + * Gets the user content manager associated to @web_view, or %NULL if the + * view does not have an user content manager. + * + * Returns: (transfer none): the #WebKitUserContentManager associated with the view * - * Returns: (transfer none): the #WebKitWebViewGroup to which the view belongs + * Since: 2.6 */ -WebKitWebViewGroup* webkit_web_view_get_group(WebKitWebView* webView) +WebKitUserContentManager* webkit_web_view_get_user_content_manager(WebKitWebView* webView) { - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr); - if (webView->priv->group) - return webView->priv->group.get(); + return webView->priv->userContentManager.get(); +} - return webkitWebContextGetDefaultWebViewGroup(webView->priv->context); +/** + * webkit_web_view_is_ephemeral: + * @web_view: a #WebKitWebView + * + * Get whether a #WebKitWebView is ephemeral. To create an ephemeral #WebKitWebView you need to + * use g_object_new() and pass is-ephemeral propery with %TRUE value. See + * #WebKitWebView:is-ephemeral for more details. + * If @web_view was created with a ephemeral #WebKitWebView:related-view or an + * ephemeral #WebKitWebView:web-context it will also be ephemeral. + * + * Returns: %TRUE if @web_view is ephemeral or %FALSE otherwise. + * + * Since: 2.16 + */ +gboolean webkit_web_view_is_ephemeral(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE); + + return webView->priv->isEphemeral; +} + +/** + * webkit_web_view_get_website_data_manager: + * @web_view: a #WebKitWebView + * + * Get the #WebKitWebsiteDataManager associated to @web_view. If @web_view is not ephemeral, + * the returned #WebKitWebsiteDataManager will be the same as the #WebKitWebsiteDataManager + * of @web_view's #WebKitWebContext. + * + * Returns: (transfer none): a #WebKitWebsiteDataManager + * + * Since: 2.16 + */ +WebKitWebsiteDataManager* webkit_web_view_get_website_data_manager(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr); + + if (webView->priv->websiteDataManager) + return webView->priv->websiteDataManager.get(); + + return webkit_web_context_get_website_data_manager(webView->priv->context.get()); +} + +/** + * webkit_web_view_try_close: + * @web_view: a #WebKitWebView + * + * Tries to close the @web_view. This will fire the onbeforeunload event + * to ask the user for confirmation to close the page. If there isn't an + * onbeforeunload event handler or the user confirms to close the page, + * the #WebKitWebView::close signal is emitted, otherwise nothing happens. + * + * Since: 2.12 + */ +void webkit_web_view_try_close(WebKitWebView *webView) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + if (getPage(webView)->tryClose()) + webkitWebViewClosePage(webView); } /** @@ -2067,6 +2416,45 @@ void webkit_web_view_load_plain_text(WebKitWebView* webView, const gchar* plainT getPage(webView)->loadPlainTextString(String::fromUTF8(plainText)); } +static void releaseGBytes(unsigned char*, const void* bytes) +{ + // Balanced by g_bytes_ref in webkit_web_view_load_bytes(). + g_bytes_unref(static_cast<GBytes*>(const_cast<void*>(bytes))); +} + +/** + * webkit_web_view_load_bytes: + * @web_view: a #WebKitWebView + * @bytes: input data to load + * @mime_type: (allow-none): the MIME type of @bytes, or %NULL + * @encoding: (allow-none): the character encoding of @bytes, or %NULL + * @base_uri: (allow-none): the base URI for relative locations or %NULL + * + * Load the specified @bytes into @web_view using the given @mime_type and @encoding. + * When @mime_type is %NULL, it defaults to "text/html". + * When @encoding is %NULL, it defaults to "UTF-8". + * When @base_uri is %NULL, it defaults to "about:blank". + * You can monitor the load operation by connecting to #WebKitWebView::load-changed signal. + * + * Since: 2.6 + */ +void webkit_web_view_load_bytes(WebKitWebView* webView, GBytes* bytes, const char* mimeType, const char* encoding, const char* baseURI) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(bytes); + + gsize bytesDataSize; + gconstpointer bytesData = g_bytes_get_data(bytes, &bytesDataSize); + g_return_if_fail(bytesDataSize); + + // Balanced by g_bytes_unref in releaseGBytes. + g_bytes_ref(bytes); + + Ref<API::Data> data = API::Data::createWithoutCopying(static_cast<const unsigned char*>(bytesData), bytesDataSize, releaseGBytes, bytes); + getPage(webView)->loadData(data.ptr(), mimeType ? String::fromUTF8(mimeType) : String::fromUTF8("text/html"), + encoding ? String::fromUTF8(encoding) : String::fromUTF8("UTF-8"), String::fromUTF8(baseURI)); +} + /** * webkit_web_view_load_request: * @web_view: a #WebKitWebView @@ -2130,7 +2518,9 @@ void webkit_web_view_reload(WebKitWebView* webView) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); - getPage(webView)->reload(false); + const bool reloadFromOrigin = false; + const bool contentBlockersEnabled = true; + getPage(webView)->reload(reloadFromOrigin, contentBlockersEnabled); } /** @@ -2144,7 +2534,9 @@ void webkit_web_view_reload_bypass_cache(WebKitWebView* webView) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); - getPage(webView)->reload(true); + const bool reloadFromOrigin = true; + const bool contentBlockersEnabled = true; + getPage(webView)->reload(reloadFromOrigin, contentBlockersEnabled); } /** @@ -2185,6 +2577,27 @@ gboolean webkit_web_view_is_loading(WebKitWebView* webView) } /** + * webkit_web_view_is_playing_audio: + * @web_view: a #WebKitWebView + * + * Gets the value of the #WebKitWebView:is-playing-audio property. + * You can monitor when a page in a #WebKitWebView is playing audio by + * connecting to the notify::is-playing-audio signal of @web_view. This + * is useful when the application wants to provide visual feedback when a + * page is producing sound. + * + * Returns: %TRUE if a page in @web_view is playing audio or %FALSE otherwise. + * + * Since: 2.8 + */ +gboolean webkit_web_view_is_playing_audio(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE); + + return getPage(webView)->isPlayingAudio(); +} + +/** * webkit_web_view_go_back: * @web_view: a #WebKitWebView * @@ -2382,7 +2795,7 @@ void webkit_web_view_set_custom_charset(WebKitWebView* webView, const gchar* cha gdouble webkit_web_view_get_estimated_load_progress(WebKitWebView* webView) { g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); - return webView->priv->estimatedLoadProgress; + return getPage(webView)->pageLoadState().estimatedProgress(); } /** @@ -2423,16 +2836,30 @@ void webkit_web_view_go_to_back_forward_list_item(WebKitWebView* webView, WebKit * @web_view: a #WebKitWebView * @settings: a #WebKitSettings * - * Sets the #WebKitSettings to be applied to @web_view. - * This is a convenient method to set new settings to the - * #WebKitWebViewGroup @web_view belongs to. - * New settings are applied immediately on all #WebKitWebView<!-- -->s - * in the @web_view group. - * See also webkit_web_view_group_set_settings(). + * Sets the #WebKitSettings to be applied to @web_view. The + * existing #WebKitSettings of @web_view will be replaced by + * @settings. New settings are applied immediately on @web_view. + * The same #WebKitSettings object can be shared + * by multiple #WebKitWebView<!-- -->s. */ void webkit_web_view_set_settings(WebKitWebView* webView, WebKitSettings* settings) { - webkit_web_view_group_set_settings(webkit_web_view_get_group(webView), settings); + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); + + if (webView->priv->settings == settings) + return; + + // The "settings" property is set on construction, and in that + // case webkit_web_view_set_settings() will be called *before* + // any settings have been assigned. In that case there are no + // signal handlers to disconnect. + if (webView->priv->settings) + webkitWebViewDisconnectSettingsSignalHandlers(webView); + + webView->priv->settings = settings; + webkitWebViewUpdateSettings(webView); + g_object_notify(G_OBJECT(webView), "settings"); } /** @@ -2440,19 +2867,25 @@ void webkit_web_view_set_settings(WebKitWebView* webView, WebKitSettings* settin * @web_view: a #WebKitWebView * * Gets the #WebKitSettings currently applied to @web_view. - * This is a convenient method to get the settings of the - * #WebKitWebViewGroup @web_view belongs to. - * #WebKitSettings objects are shared by all the #WebKitWebView<!-- -->s - * in the same #WebKitWebViewGroup, so modifying + * If no other #WebKitSettings have been explicitly applied to + * @web_view with webkit_web_view_set_settings(), the default + * #WebKitSettings will be returned. This method always returns + * a valid #WebKitSettings object. + * To modify any of the @web_view settings, you can either create + * a new #WebKitSettings object with webkit_settings_new(), setting + * the desired preferences, and then replace the existing @web_view + * settings with webkit_web_view_set_settings() or get the existing + * @web_view settings and update it directly. #WebKitSettings objects + * can be shared by multiple #WebKitWebView<!-- -->s, so modifying * the settings of a #WebKitWebView would affect other - * #WebKitWebView<!-- -->s of the same group. - * See also webkit_web_view_group_get_settings(). + * #WebKitWebView<!-- -->s using the same #WebKitSettings. * * Returns: (transfer none): the #WebKitSettings attached to @web_view */ WebKitSettings* webkit_web_view_get_settings(WebKitWebView* webView) { - return webkit_web_view_group_get_settings(webkit_web_view_get_group(webView)); + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr); + return webView->priv->settings.get(); } /** @@ -2487,7 +2920,7 @@ void webkit_web_view_set_zoom_level(WebKitWebView* webView, gdouble zoomLevel) return; WebPageProxy* page = getPage(webView); - if (webkit_settings_get_zoom_text_only(webkit_web_view_get_settings(webView))) + if (webkit_settings_get_zoom_text_only(webView->priv->settings.get())) page->setTextZoomFactor(zoomLevel); else page->setPageZoomFactor(zoomLevel); @@ -2508,16 +2941,10 @@ gdouble webkit_web_view_get_zoom_level(WebKitWebView* webView) g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 1); WebPageProxy* page = getPage(webView); - gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(webkit_web_view_get_settings(webView)); + gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(webView->priv->settings.get()); return zoomTextOnly ? page->textZoomFactor() : page->pageZoomFactor(); } -static void didValidateCommand(WKStringRef command, bool isEnabled, int32_t state, WKErrorRef, void* context) -{ - GRefPtr<GTask> task = adoptGRef(G_TASK(context)); - g_task_return_boolean(task.get(), isEnabled); -} - /** * webkit_web_view_can_execute_editing_command: * @web_view: a #WebKitWebView @@ -2526,7 +2953,7 @@ static void didValidateCommand(WKStringRef command, bool isEnabled, int32_t stat * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied * @user_data: (closure): the data to pass to callback function * - * Asynchronously execute the given editing command. + * Asynchronously check if it is possible to execute the given editing command. * * When the operation is finished, @callback will be called. You can then call * webkit_web_view_can_execute_editing_command_finish() to get the result of the operation. @@ -2537,7 +2964,9 @@ void webkit_web_view_can_execute_editing_command(WebKitWebView* webView, const c g_return_if_fail(command); GTask* task = g_task_new(webView, cancellable, callback, userData); - getPage(webView)->validateCommand(String::fromUTF8(command), ValidateCommandCallback::create(task, didValidateCommand)); + getPage(webView)->validateCommand(String::fromUTF8(command), [task](const String&, bool isEnabled, int32_t, WebKit::CallbackBase::Error) { + g_task_return_boolean(adoptGRef(task).get(), isEnabled); + }); } /** @@ -2576,6 +3005,27 @@ void webkit_web_view_execute_editing_command(WebKitWebView* webView, const char* } /** + * webkit_web_view_execute_editing_command_with_argument: + * @web_view: a #WebKitWebView + * @command: the command to execute + * @argument: the command argument + * + * Request to execute the given @command with @argument for @web_view. You can use + * webkit_web_view_can_execute_editing_command() to check whether + * it's possible to execute the command. + * + * Since: 2.10 + */ +void webkit_web_view_execute_editing_command_with_argument(WebKitWebView* webView, const char* command, const char* argument) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(command); + g_return_if_fail(argument); + + getPage(webView)->executeEditCommand(String::fromUTF8(command), String::fromUTF8(argument)); +} + +/** * webkit_web_view_get_find_controller: * @web_view: the #WebKitWebView * @@ -2614,20 +3064,20 @@ JSGlobalContextRef webkit_web_view_get_javascript_global_context(WebKitWebView* return webView->priv->javascriptGlobalContext; } -static void webkitWebViewRunJavaScriptCallback(WKSerializedScriptValueRef wkSerializedScriptValue, WKErrorRef, void* context) +static void webkitWebViewRunJavaScriptCallback(API::SerializedScriptValue* wkSerializedScriptValue, GTask* task) { - GRefPtr<GTask> task = adoptGRef(G_TASK(context)); - if (g_task_return_error_if_cancelled(task.get())) + if (g_task_return_error_if_cancelled(task)) return; if (!wkSerializedScriptValue) { - g_task_return_new_error(task.get(), WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED, + g_task_return_new_error(task, WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED, _("An exception was raised in JavaScript")); return; } - WebKitWebView* webView = WEBKIT_WEB_VIEW(g_task_get_source_object(task.get())); - g_task_return_pointer(task.get(), webkitJavascriptResultCreate(webView, toImpl(wkSerializedScriptValue)), + WebKitWebView* webView = WEBKIT_WEB_VIEW(g_task_get_source_object(task)); + g_task_return_pointer(task, webkitJavascriptResultCreate(webView, + *wkSerializedScriptValue->internalRepresentation()), reinterpret_cast<GDestroyNotify>(webkit_javascript_result_unref)); } @@ -2640,7 +3090,7 @@ static void webkitWebViewRunJavaScriptCallback(WKSerializedScriptValueRef wkSeri * @user_data: (closure): the data to pass to callback function * * Asynchronously run @script in the context of the current page in @web_view. If - * WebKitWebSettings:enable-javascript is FALSE, this method will do nothing. + * WebKitSettings:enable-javascript is FALSE, this method will do nothing. * * When the operation is finished, @callback will be called. You can then call * webkit_web_view_run_javascript_finish() to get the result of the operation. @@ -2651,7 +3101,9 @@ void webkit_web_view_run_javascript(WebKitWebView* webView, const gchar* script, g_return_if_fail(script); GTask* task = g_task_new(webView, cancellable, callback, userData); - getPage(webView)->runJavaScriptInMainFrame(String::fromUTF8(script), ScriptValueCallback::create(task, webkitWebViewRunJavaScriptCallback)); + getPage(webView)->runJavaScriptInMainFrame(String::fromUTF8(script), [task](API::SerializedScriptValue* serializedScriptValue, bool, const WebCore::ExceptionDetails&, WebKit::CallbackBase::Error) { + webkitWebViewRunJavaScriptCallback(serializedScriptValue, adoptGRef(task).get()); + }); } /** @@ -2740,7 +3192,9 @@ static void resourcesStreamReadCallback(GObject* object, GAsyncResult* result, g WebKitWebView* webView = WEBKIT_WEB_VIEW(g_task_get_source_object(task.get())); gpointer outputStreamData = g_memory_output_stream_get_data(G_MEMORY_OUTPUT_STREAM(object)); getPage(webView)->runJavaScriptInMainFrame(String::fromUTF8(reinterpret_cast<const gchar*>(outputStreamData)), - ScriptValueCallback::create(task.leakRef(), webkitWebViewRunJavaScriptCallback)); + [task](API::SerializedScriptValue* serializedScriptValue, bool, const WebCore::ExceptionDetails&, WebKit::CallbackBase::Error) { + webkitWebViewRunJavaScriptCallback(serializedScriptValue, task.get()); + }); } /** @@ -2867,16 +3321,16 @@ static void fileReplaceContentsCallback(GObject* object, GAsyncResult* result, g g_task_return_boolean(task.get(), TRUE); } -static void getContentsAsMHTMLDataCallback(WKDataRef wkData, WKErrorRef, void* context) +static void getContentsAsMHTMLDataCallback(API::Data* wkData, GTask* taskPtr) { - GRefPtr<GTask> task = adoptGRef(G_TASK(context)); + auto task = adoptGRef(taskPtr); if (g_task_return_error_if_cancelled(task.get())) return; ViewSaveAsyncData* data = static_cast<ViewSaveAsyncData*>(g_task_get_task_data(task.get())); // We need to retain the data until the asyncronous process // initiated by the user has finished completely. - data->webData = toImpl(wkData); + data->webData = wkData; // If we are saving to a file we need to write the data on disk before finishing. if (g_task_get_source_tag(task.get()) == webkit_web_view_save_to_file) { @@ -2916,7 +3370,9 @@ void webkit_web_view_save(WebKitWebView* webView, WebKitSaveMode saveMode, GCanc GTask* task = g_task_new(webView, cancellable, callback, userData); g_task_set_source_tag(task, reinterpret_cast<gpointer>(webkit_web_view_save)); g_task_set_task_data(task, createViewSaveAsyncData(), reinterpret_cast<GDestroyNotify>(destroyViewSaveAsyncData)); - getPage(webView)->getContentsAsMHTMLData(DataCallback::create(task, getContentsAsMHTMLDataCallback), false); + getPage(webView)->getContentsAsMHTMLData([task](API::Data* data, WebKit::CallbackBase::Error) { + getContentsAsMHTMLDataCallback(data, task); + }); } /** @@ -2979,7 +3435,9 @@ void webkit_web_view_save_to_file(WebKitWebView* webView, GFile* file, WebKitSav data->file = file; g_task_set_task_data(task, data, reinterpret_cast<GDestroyNotify>(destroyViewSaveAsyncData)); - getPage(webView)->getContentsAsMHTMLData(DataCallback::create(task, getContentsAsMHTMLDataCallback), false); + getPage(webView)->getContentsAsMHTMLData([task](API::Data* data, WebKit::CallbackBase::Error) { + getContentsAsMHTMLDataCallback(data, task); + }); } /** @@ -3012,50 +3470,11 @@ gboolean webkit_web_view_save_to_file_finish(WebKitWebView* webView, GAsyncResul */ WebKitDownload* webkit_web_view_download_uri(WebKitWebView* webView, const char* uri) { - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); - g_return_val_if_fail(uri, 0); - - WebKitDownload* download = webkitWebContextStartDownload(webView->priv->context, uri, getPage(webView)); - webkitDownloadSetWebView(download, webView); - - return download; -} - -/** - * webkit_web_view_set_view_mode: - * @web_view: a #WebKitWebView - * @view_mode: a #WebKitViewMode - * - * Set the view mode of @web_view to @view_mode. This method should be called - * before loading new contents on @web_view so that the new #WebKitViewMode will - * be applied to the new contents. - */ -void webkit_web_view_set_view_mode(WebKitWebView* webView, WebKitViewMode viewMode) -{ - g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); - - if (webView->priv->viewMode == viewMode) - return; - - getPage(webView)->setMainFrameInViewSourceMode(viewMode == WEBKIT_VIEW_MODE_SOURCE); - - webView->priv->viewMode = viewMode; - g_object_notify(G_OBJECT(webView), "view-mode"); -} - -/** - * webkit_web_view_get_view_mode: - * @web_view: a #WebKitWebView - * - * Get the view mode of @web_view. - * - * Returns: the #WebKitViewMode of @web_view. - */ -WebKitViewMode webkit_web_view_get_view_mode(WebKitWebView* webView) -{ - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), WEBKIT_VIEW_MODE_WEB); + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr); + g_return_val_if_fail(uri, nullptr); - return webView->priv->viewMode; + GRefPtr<WebKitDownload> download = webkitWebContextStartDownload(webView->priv->context.get(), uri, getPage(webView)); + return download.leakRef(); } /** @@ -3073,10 +3492,10 @@ WebKitViewMode webkit_web_view_get_view_mode(WebKitWebView* webView) * when it's emitted with %WEBKIT_LOAD_COMMITTED event. * * Note that this function provides no information about the security of the web - * page if the current #WebKitTLSErrorsPolicy is %WEBKIT_TLS_ERRORS_POLICY_IGNORE, + * page if the current #WebKitTLSErrorsPolicy is @WEBKIT_TLS_ERRORS_POLICY_IGNORE, * as subresources of the page may be controlled by an attacker. This function * may safely be used to determine the security status of the current page only - * if the current #WebKitTLSErrorsPolicy is %WEBKIT_TLS_ERRORS_POLICY_FAIL, in + * if the current #WebKitTLSErrorsPolicy is @WEBKIT_TLS_ERRORS_POLICY_FAIL, in * which case subresources that fail certificate verification will be blocked. * * Returns: %TRUE if the @web_view connection uses HTTPS and a response has been received @@ -3090,7 +3509,10 @@ gboolean webkit_web_view_get_tls_info(WebKitWebView* webView, GTlsCertificate** if (!mainFrame) return FALSE; - const WebCore::CertificateInfo& certificateInfo = mainFrame->certificateInfo()->certificateInfo(); + auto* wkCertificateInfo = mainFrame->certificateInfo(); + g_return_val_if_fail(wkCertificateInfo, FALSE); + + const auto& certificateInfo = wkCertificateInfo->certificateInfo(); if (certificate) *certificate = certificateInfo.certificate(); if (errors) @@ -3111,15 +3533,9 @@ void webKitWebViewDidReceiveSnapshot(WebKitWebView* webView, uint64_t callbackID return; } - if (RefPtr<ShareableBitmap> image = webImage->bitmap()) - g_task_return_pointer(task.get(), image->createCairoSurface().leakRef(), reinterpret_cast<GDestroyNotify>(cairo_surface_destroy)); - else - g_task_return_pointer(task.get(), 0, 0); + g_task_return_pointer(task.get(), webImage->bitmap().createCairoSurface().leakRef(), reinterpret_cast<GDestroyNotify>(cairo_surface_destroy)); } -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_SNAPSHOT_REGION_VISIBLE, SnapshotRegionVisible); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_SNAPSHOT_REGION_FULL_DOCUMENT, SnapshotRegionFullDocument); - static inline unsigned webKitSnapshotOptionsToSnapshotOptions(WebKitSnapshotOptions options) { SnapshotOptions snapshotOptions = 0; @@ -3130,6 +3546,19 @@ static inline unsigned webKitSnapshotOptionsToSnapshotOptions(WebKitSnapshotOpti return snapshotOptions; } +static inline SnapshotRegion toSnapshotRegion(WebKitSnapshotRegion region) +{ + switch (region) { + case WEBKIT_SNAPSHOT_REGION_VISIBLE: + return SnapshotRegionVisible; + case WEBKIT_SNAPSHOT_REGION_FULL_DOCUMENT: + return SnapshotRegionFullDocument; + default: + ASSERT_NOT_REACHED(); + return SnapshotRegionVisible; + } +} + static inline uint64_t generateSnapshotCallbackID() { static uint64_t uniqueCallbackID = 1; @@ -3139,8 +3568,8 @@ static inline uint64_t generateSnapshotCallbackID() /** * webkit_web_view_get_snapshot: * @web_view: a #WebKitWebView - * @options: #WebKitSnapshotOptions for the snapshot * @region: the #WebKitSnapshotRegion for this snapshot + * @options: #WebKitSnapshotOptions for the snapshot * @cancellable: (allow-none): a #GCancellable * @callback: (scope async): a #GAsyncReadyCallback * @user_data: (closure): user data @@ -3156,14 +3585,15 @@ void webkit_web_view_get_snapshot(WebKitWebView* webView, WebKitSnapshotRegion r { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); - ImmutableDictionary::MapType message; + API::Dictionary::MapType message; uint64_t callbackID = generateSnapshotCallbackID(); message.set(String::fromUTF8("SnapshotOptions"), API::UInt64::create(static_cast<uint64_t>(webKitSnapshotOptionsToSnapshotOptions(options)))); - message.set(String::fromUTF8("SnapshotRegion"), API::UInt64::create(static_cast<uint64_t>(region))); + message.set(String::fromUTF8("SnapshotRegion"), API::UInt64::create(static_cast<uint64_t>(toSnapshotRegion(region)))); message.set(String::fromUTF8("CallbackID"), API::UInt64::create(callbackID)); + message.set(String::fromUTF8("TransparentBackground"), API::Boolean::create(options & WEBKIT_SNAPSHOT_OPTIONS_TRANSPARENT_BACKGROUND)); webView->priv->snapshotResultsMap.set(callbackID, adoptGRef(g_task_new(webView, cancellable, callback, userData))); - getPage(webView)->postMessageToInjectedBundle(String::fromUTF8("GetSnapshot"), ImmutableDictionary::create(std::move(message)).get()); + getPage(webView)->postMessageToInjectedBundle(String::fromUTF8("GetSnapshot"), API::Dictionary::create(WTFMove(message)).ptr()); } /** @@ -3190,3 +3620,173 @@ void webkitWebViewWebProcessCrashed(WebKitWebView* webView) g_signal_emit(webView, signals[WEB_PROCESS_CRASHED], 0, &returnValue); } +/** + * webkit_web_view_set_background_color: + * @web_view: a #WebKitWebView + * @rgba: a #GdkRGBA + * + * Sets the color that will be used to draw the @web_view background before + * the actual contents are rendered. Note that if the web page loaded in @web_view + * specifies a background color, it will take precedence over the @rgba color. + * By default the @web_view background color is opaque white. + * Note that the parent window must have a RGBA visual and + * #GtkWidget:app-paintable property set to %TRUE for backgrounds colors to work. + * + * <informalexample><programlisting> + * static void browser_window_set_background_color (BrowserWindow *window, + * const GdkRGBA *rgba) + * { + * WebKitWebView *web_view; + * GdkScreen *screen = gtk_window_get_screen (GTK_WINDOW (window)); + * GdkVisual *rgba_visual = gdk_screen_get_rgba_visual (screen); + * + * if (!rgba_visual) + * return; + * + * gtk_widget_set_visual (GTK_WIDGET (window), rgba_visual); + * gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE); + * + * web_view = browser_window_get_web_view (window); + * webkit_web_view_set_background_color (web_view, rgba); + * } + * </programlisting></informalexample> + * + * Since: 2.8 + */ +void webkit_web_view_set_background_color(WebKitWebView* webView, const GdkRGBA* rgba) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(rgba); + + Color color(*rgba); + WebPageProxy* page = getPage(webView); + if (page->backgroundColor() == color) + return; + + page->setBackgroundColor(color); + page->setDrawsBackground(color == Color::white); +} + +/** + * webkit_web_view_get_background_color: + * @web_view: a #WebKitWebView + * @rgba: (out): a #GdkRGBA to fill in with the background color + * + * Gets the color that is used to draw the @web_view background before + * the actual contents are rendered. + * For more information see also webkit_web_view_set_background_color() + * + * Since: 2.8 + */ +void webkit_web_view_get_background_color(WebKitWebView* webView, GdkRGBA* rgba) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(rgba); + + *rgba = getPage(webView)->backgroundColor(); +} + +/* + * webkit_web_view_is_editable: + * @web_view: a #WebKitWebView + * + * Gets whether the user is allowed to edit the HTML document. When @web_view + * is not editable an element in the HTML document can only be edited if the + * CONTENTEDITABLE attribute has been set on the element or one of its parent + * elements. By default a #WebKitWebView is not editable. + * + * Returns: %TRUE if the user is allowed to edit the HTML document, or %FALSE otherwise. + * + * Since: 2.8 + */ +gboolean webkit_web_view_is_editable(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE); + + return getPage(webView)->isEditable(); +} + +/** + * webkit_web_view_set_editable: + * @web_view: a #WebKitWebView + * @editable: a #gboolean indicating the editable state + * + * Sets whether the user is allowed to edit the HTML document. + * + * If @editable is %TRUE, @web_view allows the user to edit the HTML document. If + * @editable is %FALSE, an element in @web_view's document can only be edited if the + * CONTENTEDITABLE attribute has been set on the element or one of its parent + * elements. By default a #WebKitWebView is not editable. + * + * Normally, a HTML document is not editable unless the elements within the + * document are editable. This function provides a way to make the contents + * of a #WebKitWebView editable without altering the document or DOM structure. + * + * Since: 2.8 + */ +void webkit_web_view_set_editable(WebKitWebView* webView, gboolean editable) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + + if (editable == getPage(webView)->isEditable()) + return; + + getPage(webView)->setEditable(editable); + + g_object_notify(G_OBJECT(webView), "editable"); +} + +/** + * webkit_web_view_get_editor_state: + * @web_view: a #WebKitWebView + * + * Gets the web editor state of @web_view. + * + * Returns: (transfer none): the #WebKitEditorState of the view + * + * Since: 2.10 + */ +WebKitEditorState* webkit_web_view_get_editor_state(WebKitWebView *webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr); + + if (!webView->priv->editorState) + webView->priv->editorState = adoptGRef(webkitEditorStateCreate(getPage(webView)->editorState())); + + return webView->priv->editorState.get(); +} + +/** + * webkit_web_view_get_session_state: + * @web_view: a #WebKitWebView + * + * Gets the current session state of @web_view + * + * Returns: (transfer full): a #WebKitWebViewSessionState + * + * Since: 2.12 + */ +WebKitWebViewSessionState* webkit_web_view_get_session_state(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr); + + SessionState sessionState = getPage(webView)->sessionState(nullptr); + return webkitWebViewSessionStateCreate(WTFMove(sessionState)); +} + +/** + * webkit_web_view_restore_session_state: + * @web_view: a #WebKitWebView + * @state: a #WebKitWebViewSessionState + * + * Restore the @web_view session state from @state + * + * Since: 2.12 + */ +void webkit_web_view_restore_session_state(WebKitWebView* webView, WebKitWebViewSessionState* state) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(state); + + getPage(webView)->restoreFromSessionState(webkitWebViewSessionStateGetSessionState(state), false); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h index 493c68d18..4b524f15d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h @@ -32,22 +32,27 @@ #include <webkit2/WebKitAuthenticationRequest.h> #include <webkit2/WebKitBackForwardList.h> #include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitColorChooserRequest.h> +#include <webkit2/WebKitEditorState.h> #include <webkit2/WebKitFileChooserRequest.h> #include <webkit2/WebKitFindController.h> #include <webkit2/WebKitFormSubmissionRequest.h> #include <webkit2/WebKitForwardDeclarations.h> #include <webkit2/WebKitHitTestResult.h> #include <webkit2/WebKitJavascriptResult.h> +#include <webkit2/WebKitNavigationAction.h> +#include <webkit2/WebKitNotification.h> #include <webkit2/WebKitPermissionRequest.h> #include <webkit2/WebKitPolicyDecision.h> #include <webkit2/WebKitScriptDialog.h> #include <webkit2/WebKitSettings.h> #include <webkit2/WebKitURIRequest.h> +#include <webkit2/WebKitUserContentManager.h> #include <webkit2/WebKitWebContext.h> #include <webkit2/WebKitWebInspector.h> #include <webkit2/WebKitWebResource.h> #include <webkit2/WebKitWebViewBase.h> -#include <webkit2/WebKitWebViewGroup.h> +#include <webkit2/WebKitWebViewSessionState.h> #include <webkit2/WebKitWindowProperties.h> G_BEGIN_DECLS @@ -150,23 +155,12 @@ typedef enum { } WebKitInsecureContentEvent; /** - * WebKitViewMode: - * @WEBKIT_VIEW_MODE_WEB: The normal view mode to display web contents. - * @WEBKIT_VIEW_MODE_SOURCE: The source mode to display web source code. - * - * Enum values to specify the different ways in which a #WebKitWebView - * can display a web page. - */ -typedef enum { - WEBKIT_VIEW_MODE_WEB, - WEBKIT_VIEW_MODE_SOURCE -} WebKitViewMode; - -/** * WebKitSnapshotOptions: * @WEBKIT_SNAPSHOT_OPTIONS_NONE: Do not include any special options. * @WEBKIT_SNAPSHOT_OPTIONS_INCLUDE_SELECTION_HIGHLIGHTING: Whether to include in the * snapshot the highlight of the selected content. + * @WEBKIT_SNAPSHOT_OPTIONS_TRANSPARENT_BACKGROUND: Do not fill the background with white before + * rendering the snapshot. Since 2.8 * * Enum values used to specify options when taking a snapshot * from a #WebKitWebView. @@ -174,6 +168,7 @@ typedef enum { typedef enum { WEBKIT_SNAPSHOT_OPTIONS_NONE = 0, WEBKIT_SNAPSHOT_OPTIONS_INCLUDE_SELECTION_HIGHLIGHTING = 1 << 0, + WEBKIT_SNAPSHOT_OPTIONS_TRANSPARENT_BACKGROUND = 1 << 1, } WebKitSnapshotOptions; /** @@ -207,7 +202,8 @@ struct _WebKitWebViewClass { const gchar *failing_uri, GError *error); - GtkWidget *(* create) (WebKitWebView *web_view); + GtkWidget *(* create) (WebKitWebView *web_view, + WebKitNavigationAction *navigation_action); void (* ready_to_show) (WebKitWebView *web_view); void (* run_as_modal) (WebKitWebView *web_view); void (* close) (WebKitWebView *web_view); @@ -246,14 +242,18 @@ struct _WebKitWebViewClass { gboolean (* authenticate) (WebKitWebView *web_view, WebKitAuthenticationRequest *request); gboolean (* load_failed_with_tls_errors) (WebKitWebView *web_view, - WebKitCertificateInfo *info, - const gchar *host); + const gchar *failing_uri, + GTlsCertificate *certificate, + GTlsCertificateFlags errors); + gboolean (* show_notification) (WebKitWebView *web_view, + WebKitNotification *notification); + gboolean (* run_color_chooser) (WebKitWebView *web_view, + WebKitColorChooserRequest *request); + void (*_webkit_reserved0) (void); void (*_webkit_reserved1) (void); void (*_webkit_reserved2) (void); void (*_webkit_reserved3) (void); - void (*_webkit_reserved4) (void); - void (*_webkit_reserved5) (void); }; WEBKIT_API GType @@ -266,16 +266,25 @@ WEBKIT_API GtkWidget * webkit_web_view_new_with_context (WebKitWebContext *context); WEBKIT_API GtkWidget * +webkit_web_view_new_with_settings (WebKitSettings *settings); + +WEBKIT_API GtkWidget * webkit_web_view_new_with_related_view (WebKitWebView *web_view); WEBKIT_API GtkWidget * -webkit_web_view_new_with_group (WebKitWebViewGroup *group); +webkit_web_view_new_with_user_content_manager (WebKitUserContentManager *user_content_manager); + +WEBKIT_API gboolean +webkit_web_view_is_ephemeral (WebKitWebView *web_view); + +WEBKIT_API WebKitWebsiteDataManager * +webkit_web_view_get_website_data_manager (WebKitWebView *web_view); WEBKIT_API WebKitWebContext * webkit_web_view_get_context (WebKitWebView *web_view); -WEBKIT_API WebKitWebViewGroup * -webkit_web_view_get_group (WebKitWebView *web_view); +WEBKIT_API void +webkit_web_view_try_close (WebKitWebView *web_view); WEBKIT_API void webkit_web_view_load_uri (WebKitWebView *web_view, @@ -295,6 +304,13 @@ webkit_web_view_load_plain_text (WebKitWebView const gchar *plain_text); WEBKIT_API void +webkit_web_view_load_bytes (WebKitWebView *web_view, + GBytes *bytes, + const gchar *mime_type, + const gchar *encoding, + const gchar *base_uri); + +WEBKIT_API void webkit_web_view_load_request (WebKitWebView *web_view, WebKitURIRequest *request); @@ -304,6 +320,9 @@ webkit_web_view_stop_loading (WebKitWebView WEBKIT_API gboolean webkit_web_view_is_loading (WebKitWebView *web_view); +WEBKIT_API gboolean +webkit_web_view_is_playing_audio (WebKitWebView *web_view); + WEBKIT_API guint64 webkit_web_view_get_page_id (WebKitWebView *web_view); @@ -382,6 +401,11 @@ WEBKIT_API void webkit_web_view_execute_editing_command (WebKitWebView *web_view, const gchar *command); +WEBKIT_API void +webkit_web_view_execute_editing_command_with_argument(WebKitWebView *web_view, + const char *command, + const char *argument); + WEBKIT_API WebKitFindController * webkit_web_view_get_find_controller (WebKitWebView *web_view); @@ -450,13 +474,6 @@ WEBKIT_API WebKitDownload * webkit_web_view_download_uri (WebKitWebView *web_view, const char *uri); -WEBKIT_API void -webkit_web_view_set_view_mode (WebKitWebView *web_view, - WebKitViewMode view_mode); - -WEBKIT_API WebKitViewMode -webkit_web_view_get_view_mode (WebKitWebView *web_view); - WEBKIT_API gboolean webkit_web_view_get_tls_info (WebKitWebView *web_view, GTlsCertificate **certificate, @@ -473,6 +490,35 @@ WEBKIT_API cairo_surface_t * webkit_web_view_get_snapshot_finish (WebKitWebView *web_view, GAsyncResult *result, GError **error); + +WEBKIT_API WebKitUserContentManager * +webkit_web_view_get_user_content_manager (WebKitWebView *web_view); + +WEBKIT_API void +webkit_web_view_set_background_color (WebKitWebView *web_view, + const GdkRGBA *rgba); + +WEBKIT_API void +webkit_web_view_get_background_color (WebKitWebView *web_view, + GdkRGBA *rgba); + +WEBKIT_API gboolean +webkit_web_view_is_editable (WebKitWebView *web_view); + +WEBKIT_API void +webkit_web_view_set_editable (WebKitWebView *web_view, + gboolean editable); + +WEBKIT_API WebKitEditorState * +webkit_web_view_get_editor_state (WebKitWebView *web_view); + +WEBKIT_API WebKitWebViewSessionState * +webkit_web_view_get_session_state (WebKitWebView *web_view); + +WEBKIT_API void +webkit_web_view_restore_session_state (WebKitWebView *web_view, + WebKitWebViewSessionState *state); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp index b22c71fa1..b057a5a44 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp @@ -29,15 +29,20 @@ #include "config.h" #include "WebKitWebViewBase.h" +#include "APIPageConfiguration.h" +#include "AcceleratedBackingStore.h" +#include "ActivityState.h" #include "DrawingAreaProxyImpl.h" +#include "InputMethodFilter.h" +#include "KeyBindingTranslator.h" +#include "NativeWebKeyboardEvent.h" #include "NativeWebMouseEvent.h" #include "NativeWebWheelEvent.h" #include "PageClientImpl.h" -#include "ViewState.h" -#include "WebContext.h" #include "WebEventFactory.h" #include "WebFullScreenClientGtk.h" #include "WebInspectorProxy.h" +#include "WebKit2Initialize.h" #include "WebKitAuthenticationDialog.h" #include "WebKitPrivate.h" #include "WebKitWebViewBaseAccessible.h" @@ -45,37 +50,31 @@ #include "WebPageGroup.h" #include "WebPageProxy.h" #include "WebPreferences.h" -#include "WebViewBaseInputMethodFilter.h" +#include "WebProcessPool.h" +#include "WebUserContentControllerProxy.h" #include <WebCore/CairoUtilities.h> -#include <WebCore/ClipboardUtilitiesGtk.h> -#include <WebCore/DataObjectGtk.h> -#include <WebCore/DragData.h> -#include <WebCore/DragIcon.h> #include <WebCore/GUniquePtrGtk.h> -#include <WebCore/GtkClickCounter.h> -#include <WebCore/GtkDragAndDropHelper.h> -#include <WebCore/GtkTouchContextHelper.h> #include <WebCore/GtkUtilities.h> #include <WebCore/GtkVersioning.h> #include <WebCore/NotImplemented.h> #include <WebCore/PasteboardHelper.h> +#include <WebCore/PlatformDisplay.h> #include <WebCore/RefPtrCairo.h> #include <WebCore/Region.h> #include <gdk/gdk.h> #include <gdk/gdkkeysyms.h> -#ifdef GDK_WINDOWING_X11 -#include <gdk/gdkx.h> -#endif +#include <glib/gi18n-lib.h> +#include <memory> #include <wtf/HashMap.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> #if ENABLE(FULLSCREEN_API) #include "WebFullScreenManagerProxy.h" #endif -#if USE(TEXTURE_MAPPER_GL) && defined(GDK_WINDOWING_X11) -#include <WebCore/RedirectedXCompositeWindow.h> +#if PLATFORM(X11) +#include <gdk/gdkx.h> #endif // gtk_widget_get_scale_factor() appeared in GTK 3.10, but we also need @@ -85,130 +84,200 @@ using namespace WebKit; using namespace WebCore; -typedef HashMap<GtkWidget*, IntRect> WebKitWebViewChildrenMap; +struct ClickCounter { +public: + void reset() + { + currentClickCount = 0; + previousClickPoint = IntPoint(); + previousClickTime = 0; + previousClickButton = 0; + } -#if USE(TEXTURE_MAPPER_GL) -void redirectedWindowDamagedCallback(void* data); -#endif + int currentClickCountForGdkButtonEvent(GdkEventButton* buttonEvent) + { + GdkEvent* event = reinterpret_cast<GdkEvent*>(buttonEvent); + int doubleClickDistance = 250; + int doubleClickTime = 5; + g_object_get(gtk_settings_get_for_screen(gdk_event_get_screen(event)), + "gtk-double-click-distance", &doubleClickDistance, "gtk-double-click-time", &doubleClickTime, nullptr); + + // GTK+ only counts up to triple clicks, but WebCore wants to know about + // quadruple clicks, quintuple clicks, ad infinitum. Here, we replicate the + // GDK logic for counting clicks. + guint32 eventTime = gdk_event_get_time(event); + if (!eventTime) { + // Real events always have a non-zero time, but events synthesized + // by the WTR do not and we must calculate a time manually. This time + // is not calculated in the WTR, because GTK+ does not work well with + // anything other than GDK_CURRENT_TIME on synthesized events. + GTimeVal timeValue; + g_get_current_time(&timeValue); + eventTime = (timeValue.tv_sec * 1000) + (timeValue.tv_usec / 1000); + } + + if ((event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) + || ((std::abs(buttonEvent->x - previousClickPoint.x()) < doubleClickDistance) + && (std::abs(buttonEvent->y - previousClickPoint.y()) < doubleClickDistance) + && (eventTime - previousClickTime < static_cast<unsigned>(doubleClickTime)) + && (buttonEvent->button == previousClickButton))) + currentClickCount++; + else + currentClickCount = 1; + + double x, y; + gdk_event_get_coords(event, &x, &y); + previousClickPoint = IntPoint(x, y); + previousClickButton = buttonEvent->button; + previousClickTime = eventTime; + + return currentClickCount; + } + +private: + int currentClickCount; + IntPoint previousClickPoint; + unsigned previousClickButton; + int previousClickTime; +}; + +typedef HashMap<GtkWidget*, IntRect> WebKitWebViewChildrenMap; +typedef HashMap<uint32_t, GUniquePtr<GdkEvent>> TouchEventsMap; struct _WebKitWebViewBasePrivate { + _WebKitWebViewBasePrivate() + : updateActivityStateTimer(RunLoop::main(), this, &_WebKitWebViewBasePrivate::updateActivityStateTimerFired) + { + } + + void updateActivityStateTimerFired() + { + if (!pageProxy) + return; + pageProxy->activityStateDidChange(activityStateFlagsToUpdate); + activityStateFlagsToUpdate = ActivityState::NoFlags; + } + WebKitWebViewChildrenMap children; - OwnPtr<PageClientImpl> pageClient; + std::unique_ptr<PageClientImpl> pageClient; RefPtr<WebPageProxy> pageProxy; bool shouldForwardNextKeyEvent; - GtkClickCounter clickCounter; + bool shouldForwardNextWheelEvent; + ClickCounter clickCounter; CString tooltipText; IntRect tooltipArea; -#if ENABLE(DRAG_SUPPORT) - GtkDragAndDropHelper dragAndDropHelper; -#endif - DragIcon dragIcon; -#if !GTK_CHECK_VERSION(3, 13, 4) - IntSize resizerSize; -#endif GRefPtr<AtkObject> accessible; - bool needsResizeOnMap; GtkWidget* authenticationDialog; GtkWidget* inspectorView; AttachmentSide inspectorAttachmentSide; unsigned inspectorViewSize; GUniquePtr<GdkEvent> contextMenuEvent; WebContextMenuProxyGtk* activeContextMenuProxy; - WebViewBaseInputMethodFilter inputMethodFilter; - GtkTouchContextHelper touchContext; + InputMethodFilter inputMethodFilter; + KeyBindingTranslator keyBindingTranslator; + TouchEventsMap touchEvents; + IntSize contentsSize; GtkWindow* toplevelOnScreenWindow; -#if !GTK_CHECK_VERSION(3, 13, 4) - unsigned long toplevelResizeGripVisibilityID; -#endif unsigned long toplevelFocusInEventID; unsigned long toplevelFocusOutEventID; - unsigned long toplevelVisibilityEventID; + unsigned long toplevelWindowStateEventID; + unsigned long toplevelWindowRealizedID; // View State. - bool isInWindowActive : 1; - bool isFocused : 1; - bool isVisible : 1; - bool isWindowVisible : 1; + ActivityState::Flags activityState; + ActivityState::Flags activityStateFlagsToUpdate; + RunLoop::Timer<WebKitWebViewBasePrivate> updateActivityStateTimer; WebKitWebViewBaseDownloadRequestHandler downloadHandler; #if ENABLE(FULLSCREEN_API) bool fullScreenModeActive; WebFullScreenClientGtk fullScreenClient; + GRefPtr<GDBusProxy> screenSaverProxy; + GRefPtr<GCancellable> screenSaverInhibitCancellable; + unsigned screenSaverCookie; +#endif + + std::unique_ptr<AcceleratedBackingStore> acceleratedBackingStore; + +#if ENABLE(DRAG_SUPPORT) + std::unique_ptr<DragAndDropHandler> dragAndDropHandler; #endif -#if USE(TEXTURE_MAPPER_GL) - OwnPtr<RedirectedXCompositeWindow> redirectedWindow; +#if HAVE(GTK_GESTURES) + std::unique_ptr<GestureController> gestureController; #endif }; WEBKIT_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_CONTAINER) -#if !GTK_CHECK_VERSION(3, 13, 4) -static void webkitWebViewBaseNotifyResizerSize(WebKitWebViewBase* webViewBase) +static void webkitWebViewBaseScheduleUpdateActivityState(WebKitWebViewBase* webViewBase, ActivityState::Flags flagsToUpdate) { WebKitWebViewBasePrivate* priv = webViewBase->priv; - if (!priv->toplevelOnScreenWindow) + priv->activityStateFlagsToUpdate |= flagsToUpdate; + if (priv->updateActivityStateTimer.isActive()) return; - gboolean resizerVisible; - g_object_get(G_OBJECT(priv->toplevelOnScreenWindow), "resize-grip-visible", &resizerVisible, NULL); - - IntSize resizerSize; - if (resizerVisible) { - GdkRectangle resizerRect; - gtk_window_get_resize_grip_area(priv->toplevelOnScreenWindow, &resizerRect); - GdkRectangle allocation; - gtk_widget_get_allocation(GTK_WIDGET(webViewBase), &allocation); - if (gdk_rectangle_intersect(&resizerRect, &allocation, 0)) - resizerSize = IntSize(resizerRect.width, resizerRect.height); - } - - if (resizerSize != priv->resizerSize) { - priv->resizerSize = resizerSize; - priv->pageProxy->setWindowResizerSize(resizerSize); - } + priv->updateActivityStateTimer.startOneShot(0); } -static void toplevelWindowResizeGripVisibilityChanged(GObject*, GParamSpec*, WebKitWebViewBase* webViewBase) +static gboolean toplevelWindowFocusInEvent(GtkWidget* widget, GdkEventFocus*, WebKitWebViewBase* webViewBase) { - webkitWebViewBaseNotifyResizerSize(webViewBase); + // Spurious focus in events can occur when the window is hidden. + if (!gtk_widget_get_visible(widget)) + return FALSE; + + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (priv->activityState & ActivityState::WindowIsActive) + return FALSE; + + priv->activityState |= ActivityState::WindowIsActive; + webkitWebViewBaseScheduleUpdateActivityState(webViewBase, ActivityState::WindowIsActive); + + return FALSE; } -#endif -static gboolean toplevelWindowFocusInEvent(GtkWidget* widget, GdkEventFocus*, WebKitWebViewBase* webViewBase) +static gboolean toplevelWindowFocusOutEvent(GtkWidget*, GdkEventFocus*, WebKitWebViewBase* webViewBase) { WebKitWebViewBasePrivate* priv = webViewBase->priv; - if (!priv->isInWindowActive) { - priv->isInWindowActive = true; - priv->pageProxy->viewStateDidChange(ViewState::WindowIsActive); - } + if (!(priv->activityState & ActivityState::WindowIsActive)) + return FALSE; + + priv->activityState &= ~ActivityState::WindowIsActive; + webkitWebViewBaseScheduleUpdateActivityState(webViewBase, ActivityState::WindowIsActive); return FALSE; } -static gboolean toplevelWindowFocusOutEvent(GtkWidget* widget, GdkEventFocus*, WebKitWebViewBase* webViewBase) +static gboolean toplevelWindowStateEvent(GtkWidget*, GdkEventWindowState* event, WebKitWebViewBase* webViewBase) { WebKitWebViewBasePrivate* priv = webViewBase->priv; - if (priv->isInWindowActive) { - priv->isInWindowActive = false; - priv->pageProxy->viewStateDidChange(ViewState::WindowIsActive); - } + if (!(event->changed_mask & GDK_WINDOW_STATE_ICONIFIED)) + return FALSE; + + bool visible = !(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED); + if ((visible && priv->activityState & ActivityState::IsVisible) || (!visible && !(priv->activityState & ActivityState::IsVisible))) + return FALSE; + + if (visible) + priv->activityState |= ActivityState::IsVisible; + else + priv->activityState &= ~ActivityState::IsVisible; + webkitWebViewBaseScheduleUpdateActivityState(webViewBase, ActivityState::IsVisible); return FALSE; } -static gboolean toplevelWindowVisibilityEvent(GtkWidget*, GdkEventVisibility* visibilityEvent, WebKitWebViewBase* webViewBase) +static void toplevelWindowRealized(WebKitWebViewBase* webViewBase) { + gtk_widget_realize(GTK_WIDGET(webViewBase)); + WebKitWebViewBasePrivate* priv = webViewBase->priv; - bool isWindowVisible = visibilityEvent->state != GDK_VISIBILITY_FULLY_OBSCURED; - if (priv->isWindowVisible != isWindowVisible) { - priv->isWindowVisible = isWindowVisible; - priv->pageProxy->viewStateDidChange(ViewState::IsVisible); + if (priv->toplevelWindowRealizedID) { + g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelWindowRealizedID); + priv->toplevelWindowRealizedID = 0; } - - return FALSE; } static void webkitWebViewBaseSetToplevelOnScreenWindow(WebKitWebViewBase* webViewBase, GtkWindow* window) @@ -217,12 +286,6 @@ static void webkitWebViewBaseSetToplevelOnScreenWindow(WebKitWebViewBase* webVie if (priv->toplevelOnScreenWindow == window) return; -#if !GTK_CHECK_VERSION(3, 13, 4) - if (priv->toplevelResizeGripVisibilityID) { - g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelResizeGripVisibilityID); - priv->toplevelResizeGripVisibilityID = 0; - } -#endif if (priv->toplevelFocusInEventID) { g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelFocusInEventID); priv->toplevelFocusInEventID = 0; @@ -231,36 +294,53 @@ static void webkitWebViewBaseSetToplevelOnScreenWindow(WebKitWebViewBase* webVie g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelFocusOutEventID); priv->toplevelFocusOutEventID = 0; } - if (priv->toplevelVisibilityEventID) { - g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelVisibilityEventID); - priv->toplevelVisibilityEventID = 0; + if (priv->toplevelWindowStateEventID) { + g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelWindowStateEventID); + priv->toplevelWindowStateEventID = 0; + } + if (priv->toplevelWindowRealizedID) { + g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelWindowRealizedID); + priv->toplevelWindowRealizedID = 0; } priv->toplevelOnScreenWindow = window; - priv->pageProxy->viewStateDidChange(ViewState::IsInWindow); - if (!priv->toplevelOnScreenWindow) - return; -#if !GTK_CHECK_VERSION(3, 13, 4) - webkitWebViewBaseNotifyResizerSize(webViewBase); + if (!priv->toplevelOnScreenWindow) { + ActivityState::Flags flagsToUpdate = 0; + if (priv->activityState & ActivityState::IsInWindow) { + priv->activityState &= ~ActivityState::IsInWindow; + flagsToUpdate |= ActivityState::IsInWindow; + } + if (priv->activityState & ActivityState::WindowIsActive) { + priv->activityState &= ~ActivityState::WindowIsActive; + flagsToUpdate |= ActivityState::IsInWindow; + } + if (flagsToUpdate) + webkitWebViewBaseScheduleUpdateActivityState(webViewBase, flagsToUpdate); + + return; + } - priv->toplevelResizeGripVisibilityID = - g_signal_connect(priv->toplevelOnScreenWindow, "notify::resize-grip-visible", - G_CALLBACK(toplevelWindowResizeGripVisibilityChanged), webViewBase); -#endif priv->toplevelFocusInEventID = g_signal_connect(priv->toplevelOnScreenWindow, "focus-in-event", G_CALLBACK(toplevelWindowFocusInEvent), webViewBase); priv->toplevelFocusOutEventID = g_signal_connect(priv->toplevelOnScreenWindow, "focus-out-event", G_CALLBACK(toplevelWindowFocusOutEvent), webViewBase); - priv->toplevelVisibilityEventID = - g_signal_connect(priv->toplevelOnScreenWindow, "visibility-notify-event", - G_CALLBACK(toplevelWindowVisibilityEvent), webViewBase); + priv->toplevelWindowStateEventID = + g_signal_connect(priv->toplevelOnScreenWindow, "window-state-event", G_CALLBACK(toplevelWindowStateEvent), webViewBase); + + if (gtk_widget_get_realized(GTK_WIDGET(window))) + gtk_widget_realize(GTK_WIDGET(webViewBase)); + else + priv->toplevelWindowRealizedID = g_signal_connect_swapped(window, "realize", G_CALLBACK(toplevelWindowRealized), webViewBase); } static void webkitWebViewBaseRealize(GtkWidget* widget) { + WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(widget); + WebKitWebViewBasePrivate* priv = webView->priv; + gtk_widget_set_realized(widget, TRUE); GtkAllocation allocation; @@ -281,6 +361,8 @@ static void webkitWebViewBaseRealize(GtkWidget* widget) | GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK | GDK_POINTER_MOTION_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_BUTTON_MOTION_MASK @@ -295,12 +377,30 @@ static void webkitWebViewBaseRealize(GtkWidget* widget) gtk_widget_set_window(widget, window); gdk_window_set_user_data(window, widget); +#if USE(TEXTURE_MAPPER_GL) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW) + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11) { + if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(priv->pageProxy->drawingArea())) + drawingArea->setNativeSurfaceHandleForCompositing(GDK_WINDOW_XID(window)); + } +#endif + gtk_style_context_set_background(gtk_widget_get_style_context(widget), window); + gtk_im_context_set_client_window(priv->inputMethodFilter.context(), window); +} + +static void webkitWebViewBaseUnrealize(GtkWidget* widget) +{ WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(widget); - GtkWidget* toplevel = gtk_widget_get_toplevel(widget); - if (widgetIsOnscreenToplevelWindow(toplevel)) - webkitWebViewBaseSetToplevelOnScreenWindow(webView, GTK_WINDOW(toplevel)); +#if USE(TEXTURE_MAPPER_GL) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW) + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11) { + if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(webView->priv->pageProxy->drawingArea())) + drawingArea->destroyNativeSurfaceHandleForCompositing(); + } +#endif + gtk_im_context_set_client_window(webView->priv->inputMethodFilter.context(), nullptr); + + GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->unrealize(widget); } static bool webkitWebViewChildIsInternalWidget(WebKitWebViewBase* webViewBase, GtkWidget* widget) @@ -406,8 +506,10 @@ void webkitWebViewBaseChildMoveResize(WebKitWebViewBase* webView, GtkWidget* chi static void webkitWebViewBaseDispose(GObject* gobject) { WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(gobject); + g_cancellable_cancel(webView->priv->screenSaverInhibitCancellable.get()); webkitWebViewBaseSetToplevelOnScreenWindow(webView, nullptr); webView->priv->pageProxy->close(); + webView->priv->acceleratedBackingStore = nullptr; G_OBJECT_CLASS(webkit_web_view_base_parent_class)->dispose(gobject); } @@ -417,48 +519,15 @@ static void webkitWebViewBaseConstructed(GObject* object) GtkWidget* viewWidget = GTK_WIDGET(object); gtk_widget_set_can_focus(viewWidget, TRUE); - gtk_drag_dest_set(viewWidget, static_cast<GtkDestDefaults>(0), 0, 0, - static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_PRIVATE)); - gtk_drag_dest_set_target_list(viewWidget, PasteboardHelper::defaultPasteboardHelper()->targetList()); + gtk_drag_dest_set(viewWidget, static_cast<GtkDestDefaults>(0), nullptr, 0, + static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_PRIVATE)); + gtk_drag_dest_set_target_list(viewWidget, PasteboardHelper::singleton().targetList()); WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(object)->priv; - priv->pageClient = PageClientImpl::create(viewWidget); -#if ENABLE(DRAG_SUPPORT) - priv->dragAndDropHelper.setWidget(viewWidget); -#endif - -#if USE(TEXTURE_MAPPER_GL) && defined(GDK_WINDOWING_X11) - GdkDisplay* display = gdk_display_manager_get_default_display(gdk_display_manager_get()); - if (GDK_IS_X11_DISPLAY(display)) { - priv->redirectedWindow = RedirectedXCompositeWindow::create(IntSize(1, 1), RedirectedXCompositeWindow::DoNotCreateGLContext); - if (priv->redirectedWindow) - priv->redirectedWindow->setDamageNotifyCallback(redirectedWindowDamagedCallback, object); - } -#endif - + priv->pageClient = std::make_unique<PageClientImpl>(viewWidget); priv->authenticationDialog = 0; } -#if USE(TEXTURE_MAPPER_GL) -static bool webkitWebViewRenderAcceleratedCompositingResults(WebKitWebViewBase* webViewBase, DrawingAreaProxyImpl* drawingArea, cairo_t* cr, GdkRectangle* clipRect) -{ - if (!drawingArea->isInAcceleratedCompositingMode()) - return false; - - // To avoid flashes when initializing accelerated compositing for the first - // time, we wait until we know there's a frame ready before rendering. - WebKitWebViewBasePrivate* priv = webViewBase->priv; - if (!priv->redirectedWindow) - return false; - - cairo_rectangle(cr, clipRect->x, clipRect->y, clipRect->width, clipRect->height); - cairo_surface_t* surface = priv->redirectedWindow->cairoSurfaceForWidget(GTK_WIDGET(webViewBase)); - cairo_set_source_surface(cr, surface, 0, 0); - cairo_fill(cr); - return true; -} -#endif - static gboolean webkitWebViewBaseDraw(GtkWidget* widget, cairo_t* cr) { WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); @@ -470,18 +539,11 @@ static gboolean webkitWebViewBaseDraw(GtkWidget* widget, cairo_t* cr) if (!gdk_cairo_get_clip_rectangle(cr, &clipRect)) return FALSE; -#if USE(TEXTURE_MAPPER_GL) - if (webkitWebViewRenderAcceleratedCompositingResults(webViewBase, drawingArea, cr, &clipRect)) - return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->draw(widget, cr); -#endif - - WebCore::Region unpaintedRegion; // This is simply unused. - drawingArea->paint(cr, clipRect, unpaintedRegion); - - if (webViewBase->priv->authenticationDialog) { - cairo_set_operator(cr, CAIRO_OPERATOR_OVER); - cairo_set_source_rgba(cr, 0, 0, 0, 0.5); - cairo_paint(cr); + if (webViewBase->priv->acceleratedBackingStore && drawingArea->isInAcceleratedCompositingMode()) + webViewBase->priv->acceleratedBackingStore->paint(cr, clipRect); + else { + WebCore::Region unpaintedRegion; // This is simply unused. + drawingArea->paint(cr, clipRect, unpaintedRegion); } GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->draw(widget, cr); @@ -505,8 +567,11 @@ static void webkitWebViewBaseChildAllocate(GtkWidget* child, gpointer userData) priv->children.set(child, IntRect()); } -static void resizeWebKitWebViewBaseFromAllocation(WebKitWebViewBase* webViewBase, GtkAllocation* allocation, bool sizeChanged) +static void webkitWebViewBaseSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) { + GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->size_allocate(widget, allocation); + + WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); gtk_container_foreach(GTK_CONTAINER(webViewBase), webkitWebViewBaseChildAllocate, webViewBase); IntRect viewRect(allocation->x, allocation->y, allocation->width, allocation->height); @@ -514,7 +579,7 @@ static void resizeWebKitWebViewBaseFromAllocation(WebKitWebViewBase* webViewBase if (priv->inspectorView) { GtkAllocation childAllocation = viewRect; - if (priv->inspectorAttachmentSide == AttachmentSideBottom) { + if (priv->inspectorAttachmentSide == AttachmentSide::Bottom) { int inspectorViewHeight = std::min(static_cast<int>(priv->inspectorViewSize), allocation->height); childAllocation.x = 0; childAllocation.y = allocation->height - inspectorViewHeight; @@ -535,45 +600,29 @@ static void resizeWebKitWebViewBaseFromAllocation(WebKitWebViewBase* webViewBase // never overlaps the web inspector. Thus, we need to calculate the allocation here // after calculating the inspector allocation. if (priv->authenticationDialog) { - GtkRequisition naturalSize; - gtk_widget_get_preferred_size(priv->authenticationDialog, 0, &naturalSize); - - GtkAllocation childAllocation = { - (viewRect.width() - naturalSize.width) / 2, - (viewRect.height() - naturalSize.height) / 2, - naturalSize.width, - naturalSize.height - }; + GtkRequisition minimumSize; + gtk_widget_get_preferred_size(priv->authenticationDialog, &minimumSize, nullptr); + + GtkAllocation childAllocation = { 0, 0, std::max(minimumSize.width, viewRect.width()), std::max(minimumSize.height, viewRect.height()) }; gtk_widget_size_allocate(priv->authenticationDialog, &childAllocation); } -#if USE(TEXTURE_MAPPER_GL) - if (sizeChanged && webViewBase->priv->redirectedWindow) - webViewBase->priv->redirectedWindow->resize(viewRect.size()); -#endif - - if (priv->pageProxy->drawingArea()) - priv->pageProxy->drawingArea()->setSize(viewRect.size(), IntSize(), IntSize()); - -#if !GTK_CHECK_VERSION(3, 13, 4) - webkitWebViewBaseNotifyResizerSize(webViewBase); -#endif + if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(priv->pageProxy->drawingArea())) + drawingArea->setSize(viewRect.size(), IntSize(), IntSize()); } -static void webkitWebViewBaseSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) +static void webkitWebViewBaseGetPreferredWidth(GtkWidget* widget, gint* minimumSize, gint* naturalSize) { - bool sizeChanged = gtk_widget_get_allocated_width(widget) != allocation->width - || gtk_widget_get_allocated_height(widget) != allocation->height; - - GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->size_allocate(widget, allocation); - - WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - if (sizeChanged && !gtk_widget_get_mapped(widget)) { - webViewBase->priv->needsResizeOnMap = true; - return; - } + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + *minimumSize = 0; + *naturalSize = priv->contentsSize.width(); +} - resizeWebKitWebViewBaseFromAllocation(webViewBase, allocation, sizeChanged); +static void webkitWebViewBaseGetPreferredHeight(GtkWidget* widget, gint* minimumSize, gint* naturalSize) +{ + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + *minimumSize = 0; + *naturalSize = priv->contentsSize.height(); } static void webkitWebViewBaseMap(GtkWidget* widget) @@ -582,29 +631,33 @@ static void webkitWebViewBaseMap(GtkWidget* widget) WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); WebKitWebViewBasePrivate* priv = webViewBase->priv; - if (!priv->isVisible) { - priv->isVisible = true; - priv->pageProxy->viewStateDidChange(ViewState::IsVisible); + ActivityState::Flags flagsToUpdate = 0; + if (!(priv->activityState & ActivityState::IsVisible)) + flagsToUpdate |= ActivityState::IsVisible; + if (priv->toplevelOnScreenWindow) { + if (!(priv->activityState & ActivityState::IsInWindow)) + flagsToUpdate |= ActivityState::IsInWindow; + if (gtk_window_is_active(GTK_WINDOW(priv->toplevelOnScreenWindow)) && !(priv->activityState & ActivityState::WindowIsActive)) + flagsToUpdate |= ActivityState::WindowIsActive; } - - if (!priv->needsResizeOnMap) + if (!flagsToUpdate) return; - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - resizeWebKitWebViewBaseFromAllocation(webViewBase, &allocation, true /* sizeChanged */); - priv->needsResizeOnMap = false; + priv->activityState |= flagsToUpdate; + webkitWebViewBaseScheduleUpdateActivityState(webViewBase, flagsToUpdate); } static void webkitWebViewBaseUnmap(GtkWidget* widget) { GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->unmap(widget); - WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; - if (priv->isVisible) { - priv->isVisible = false; - priv->pageProxy->viewStateDidChange(ViewState::IsVisible); - } + WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (!(priv->activityState & ActivityState::IsVisible)) + return; + + priv->activityState &= ~ActivityState::IsVisible; + webkitWebViewBaseScheduleUpdateActivityState(webViewBase, ActivityState::IsVisible); } static gboolean webkitWebViewBaseFocusInEvent(GtkWidget* widget, GdkEventFocus* event) @@ -625,17 +678,26 @@ static gboolean webkitWebViewBaseFocusOutEvent(GtkWidget* widget, GdkEventFocus* return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->focus_out_event(widget, event); } -static gboolean webkitWebViewBaseKeyPressEvent(GtkWidget* widget, GdkEventKey* event) +static gboolean webkitWebViewBaseKeyPressEvent(GtkWidget* widget, GdkEventKey* keyEvent) { WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); WebKitWebViewBasePrivate* priv = webViewBase->priv; +#if ENABLE(DEVELOPER_MODE) && OS(LINUX) + if ((keyEvent->state & GDK_CONTROL_MASK) && (keyEvent->state & GDK_SHIFT_MASK) && keyEvent->keyval == GDK_KEY_G) { + auto& preferences = priv->pageProxy->preferences(); + preferences.setResourceUsageOverlayVisible(!preferences.resourceUsageOverlayVisible()); + priv->shouldForwardNextKeyEvent = FALSE; + return TRUE; + } +#endif + if (priv->authenticationDialog) - return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_press_event(widget, event); + return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_press_event(widget, keyEvent); #if ENABLE(FULLSCREEN_API) if (priv->fullScreenModeActive) { - switch (event->keyval) { + switch (keyEvent->keyval) { case GDK_KEY_Escape: case GDK_KEY_f: case GDK_KEY_F: @@ -653,22 +715,35 @@ static gboolean webkitWebViewBaseKeyPressEvent(GtkWidget* widget, GdkEventKey* e // using gtk_main_do_event(). if (priv->shouldForwardNextKeyEvent) { priv->shouldForwardNextKeyEvent = FALSE; - return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_press_event(widget, event); + return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_press_event(widget, keyEvent); } - priv->inputMethodFilter.filterKeyEvent(event); + + // We need to copy the event as otherwise it could be destroyed before we reach the lambda body. + GUniquePtr<GdkEvent> event(gdk_event_copy(reinterpret_cast<GdkEvent*>(keyEvent))); + priv->inputMethodFilter.filterKeyEvent(keyEvent, [priv, event = WTFMove(event)](const WebCore::CompositionResults& compositionResults, InputMethodFilter::EventFakedForComposition faked) { + priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(event.get(), compositionResults, faked, + !compositionResults.compositionUpdated() ? priv->keyBindingTranslator.commandsForKeyEvent(&event->key) : Vector<String>())); + }); + return TRUE; } -static gboolean webkitWebViewBaseKeyReleaseEvent(GtkWidget* widget, GdkEventKey* event) +static gboolean webkitWebViewBaseKeyReleaseEvent(GtkWidget* widget, GdkEventKey* keyEvent) { WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); WebKitWebViewBasePrivate* priv = webViewBase->priv; if (priv->shouldForwardNextKeyEvent) { priv->shouldForwardNextKeyEvent = FALSE; - return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_release_event(widget, event); + return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_release_event(widget, keyEvent); } - priv->inputMethodFilter.filterKeyEvent(event); + + // We need to copy the event as otherwise it could be destroyed before we reach the lambda body. + GUniquePtr<GdkEvent> event(gdk_event_copy(reinterpret_cast<GdkEvent*>(keyEvent))); + priv->inputMethodFilter.filterKeyEvent(keyEvent, [priv, event = WTFMove(event)](const WebCore::CompositionResults& compositionResults, InputMethodFilter::EventFakedForComposition faked) { + priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(event.get(), compositionResults, faked, { })); + }); + return TRUE; } @@ -684,14 +759,21 @@ static gboolean webkitWebViewBaseButtonPressEvent(GtkWidget* widget, GdkEventBut priv->inputMethodFilter.notifyMouseButtonPress(); - if (!priv->clickCounter.shouldProcessButtonEvent(buttonEvent)) + // For double and triple clicks GDK sends both a normal button press event + // and a specific type (like GDK_2BUTTON_PRESS). If we detect a special press + // coming up, ignore this event as it certainly generated the double or triple + // click. The consequence of not eating this event is two DOM button press events + // are generated. + GUniquePtr<GdkEvent> nextEvent(gdk_event_peek()); + if (nextEvent && (nextEvent->any.type == GDK_2BUTTON_PRESS || nextEvent->any.type == GDK_3BUTTON_PRESS)) return TRUE; // If it's a right click event save it as a possible context menu event. if (buttonEvent->button == 3) priv->contextMenuEvent.reset(gdk_event_copy(reinterpret_cast<GdkEvent*>(buttonEvent))); + priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(reinterpret_cast<GdkEvent*>(buttonEvent), - priv->clickCounter.clickCountForGdkButtonEvent(widget, buttonEvent))); + priv->clickCounter.currentClickCountForGdkButtonEvent(buttonEvent))); return TRUE; } @@ -714,41 +796,195 @@ static gboolean webkitWebViewBaseScrollEvent(GtkWidget* widget, GdkEventScroll* WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (std::exchange(priv->shouldForwardNextWheelEvent, false)) + return FALSE; + if (priv->authenticationDialog) - return TRUE; + return FALSE; priv->pageProxy->handleWheelEvent(NativeWebWheelEvent(reinterpret_cast<GdkEvent*>(event))); return TRUE; } +static gboolean webkitWebViewBasePopupMenu(GtkWidget* widget) +{ + WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); + WebKitWebViewBasePrivate* priv = webViewBase->priv; + + GdkEvent* currentEvent = gtk_get_current_event(); + if (!currentEvent) + currentEvent = gdk_event_new(GDK_NOTHING); + priv->contextMenuEvent.reset(currentEvent); + priv->pageProxy->handleContextMenuKeyEvent(); + + return TRUE; +} + static gboolean webkitWebViewBaseMotionNotifyEvent(GtkWidget* widget, GdkEventMotion* event) { WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); WebKitWebViewBasePrivate* priv = webViewBase->priv; - if (priv->authenticationDialog) - return TRUE; + if (priv->authenticationDialog) { + auto* widgetClass = GTK_WIDGET_CLASS(webkit_web_view_base_parent_class); + return widgetClass->motion_notify_event ? widgetClass->motion_notify_event(widget, event) : FALSE; + } priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(reinterpret_cast<GdkEvent*>(event), 0 /* currentClickCount */)); - return TRUE; + return FALSE; +} + +static gboolean webkitWebViewBaseCrossingNotifyEvent(GtkWidget* widget, GdkEventCrossing* crosssingEvent) +{ + WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); + WebKitWebViewBasePrivate* priv = webViewBase->priv; + + if (priv->authenticationDialog) + return FALSE; + + // In the case of crossing events, it's very important the actual coordinates the WebProcess receives, because once the mouse leaves + // the web view, the WebProcess won't receive more events until the mouse enters again in the web view. So, if the coordinates of the leave + // event are not accurate, the WebProcess might not know the mouse left the view. This can happen because of double to integer conversion, + // if the coordinates of the leave event are for example (25.2, -0.9), the WebProcess will receive (25, 0) and any hit test will succeed + // because those coordinates are inside the web view. + GtkAllocation allocation; + gtk_widget_get_allocation(widget, &allocation); + double width = allocation.width; + double height = allocation.height; + double x = crosssingEvent->x; + double y = crosssingEvent->y; + if (x < 0 && x > -1) + x = -1; + else if (x >= width && x < width + 1) + x = width + 1; + if (y < 0 && y > -1) + y = -1; + else if (y >= height && y < height + 1) + y = height + 1; + + GdkEvent* event = reinterpret_cast<GdkEvent*>(crosssingEvent); + GUniquePtr<GdkEvent> copiedEvent; + if (x != crosssingEvent->x || y != crosssingEvent->y) { + copiedEvent.reset(gdk_event_copy(event)); + copiedEvent->crossing.x = x; + copiedEvent->crossing.y = y; + } + + priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(copiedEvent ? copiedEvent.get() : event, 0 /* currentClickCount */)); + + return FALSE; +} + +#if ENABLE(TOUCH_EVENTS) +static void appendTouchEvent(Vector<WebPlatformTouchPoint>& touchPoints, const GdkEvent* event, WebPlatformTouchPoint::TouchPointState state) +{ + gdouble x, y; + gdk_event_get_coords(event, &x, &y); + + gdouble xRoot, yRoot; + gdk_event_get_root_coords(event, &xRoot, &yRoot); + + uint32_t identifier = GPOINTER_TO_UINT(gdk_event_get_event_sequence(event)); + touchPoints.uncheckedAppend(WebPlatformTouchPoint(identifier, state, IntPoint(xRoot, yRoot), IntPoint(x, y))); +} + +static inline WebPlatformTouchPoint::TouchPointState touchPointStateForEvents(const GdkEvent* current, const GdkEvent* event) +{ + if (gdk_event_get_event_sequence(current) != gdk_event_get_event_sequence(event)) + return WebPlatformTouchPoint::TouchStationary; + + switch (current->type) { + case GDK_TOUCH_UPDATE: + return WebPlatformTouchPoint::TouchMoved; + case GDK_TOUCH_BEGIN: + return WebPlatformTouchPoint::TouchPressed; + case GDK_TOUCH_END: + return WebPlatformTouchPoint::TouchReleased; + default: + return WebPlatformTouchPoint::TouchStationary; + } +} + +static void webkitWebViewBaseGetTouchPointsForEvent(WebKitWebViewBase* webViewBase, GdkEvent* event, Vector<WebPlatformTouchPoint>& touchPoints) +{ + WebKitWebViewBasePrivate* priv = webViewBase->priv; + touchPoints.reserveInitialCapacity(event->type == GDK_TOUCH_END ? priv->touchEvents.size() + 1 : priv->touchEvents.size()); + + for (const auto& it : priv->touchEvents) + appendTouchEvent(touchPoints, it.value.get(), touchPointStateForEvents(it.value.get(), event)); + + // Touch was already removed from the TouchEventsMap, add it here. + if (event->type == GDK_TOUCH_END) + appendTouchEvent(touchPoints, event, WebPlatformTouchPoint::TouchReleased); } static gboolean webkitWebViewBaseTouchEvent(GtkWidget* widget, GdkEventTouch* event) { - WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); + WebKitWebViewBasePrivate* priv = webViewBase->priv; if (priv->authenticationDialog) return TRUE; - priv->touchContext.handleEvent(reinterpret_cast<GdkEvent*>(event)); - priv->pageProxy->handleTouchEvent(NativeWebTouchEvent(reinterpret_cast<GdkEvent*>(event), priv->touchContext)); + GdkEvent* touchEvent = reinterpret_cast<GdkEvent*>(event); + uint32_t sequence = GPOINTER_TO_UINT(gdk_event_get_event_sequence(touchEvent)); + +#if HAVE(GTK_GESTURES) + GestureController& gestureController = webkitWebViewBaseGestureController(webViewBase); + if (gestureController.isProcessingGestures()) { + // If we are already processing gestures is because the WebProcess didn't handle the + // BEGIN touch event, so pass subsequent events to the GestureController. + gestureController.handleEvent(touchEvent); + // Remove the gesture event sequence from the handled touch events + // list to avoid the gesure sequence and a touch sequence of same + // ID to conflict. + priv->touchEvents.remove(sequence); + return TRUE; + } +#endif + + switch (touchEvent->type) { + case GDK_TOUCH_BEGIN: { + ASSERT(!priv->touchEvents.contains(sequence)); + GUniquePtr<GdkEvent> event(gdk_event_copy(touchEvent)); + priv->touchEvents.add(sequence, WTFMove(event)); + break; + } + case GDK_TOUCH_UPDATE: { + auto it = priv->touchEvents.find(sequence); + ASSERT(it != priv->touchEvents.end()); + it->value.reset(gdk_event_copy(touchEvent)); + break; + } + case GDK_TOUCH_END: + ASSERT(priv->touchEvents.contains(sequence)); + priv->touchEvents.remove(sequence); + break; + default: + break; + } + + Vector<WebPlatformTouchPoint> touchPoints; + webkitWebViewBaseGetTouchPointsForEvent(webViewBase, touchEvent, touchPoints); + priv->pageProxy->handleTouchEvent(NativeWebTouchEvent(reinterpret_cast<GdkEvent*>(event), WTFMove(touchPoints))); return TRUE; } +#endif // ENABLE(TOUCH_EVENTS) + +#if HAVE(GTK_GESTURES) +GestureController& webkitWebViewBaseGestureController(WebKitWebViewBase* webViewBase) +{ + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (!priv->gestureController) + priv->gestureController = std::make_unique<GestureController>(*priv->pageProxy); + return *priv->gestureController; +} +#endif -static gboolean webkitWebViewBaseQueryTooltip(GtkWidget* widget, gint x, gint y, gboolean keyboardMode, GtkTooltip* tooltip) +static gboolean webkitWebViewBaseQueryTooltip(GtkWidget* widget, gint /* x */, gint /* y */, gboolean keyboardMode, GtkTooltip* tooltip) { WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; @@ -772,39 +1008,23 @@ static gboolean webkitWebViewBaseQueryTooltip(GtkWidget* widget, gint x, gint y, } #if ENABLE(DRAG_SUPPORT) -static void webkitWebViewBaseDragDataGet(GtkWidget* widget, GdkDragContext* context, GtkSelectionData* selectionData, guint info, guint time) +static void webkitWebViewBaseDragDataGet(GtkWidget* widget, GdkDragContext* context, GtkSelectionData* selectionData, guint info, guint /* time */) { - WEBKIT_WEB_VIEW_BASE(widget)->priv->dragAndDropHelper.handleGetDragData(context, selectionData, info); + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + ASSERT(priv->dragAndDropHandler); + priv->dragAndDropHandler->fillDragData(context, selectionData, info); } static void webkitWebViewBaseDragEnd(GtkWidget* widget, GdkDragContext* context) { - WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - if (!webViewBase->priv->dragAndDropHelper.handleDragEnd(context)) - return; - - GdkDevice* device = gdk_drag_context_get_device(context); - int x = 0, y = 0; - gdk_device_get_window_at_position(device, &x, &y); - int xRoot = 0, yRoot = 0; - gdk_device_get_position(device, 0, &xRoot, &yRoot); - webViewBase->priv->pageProxy->dragEnded(IntPoint(x, y), IntPoint(xRoot, yRoot), - gdkDragActionToDragOperation(gdk_drag_context_get_selected_action(context))); + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + ASSERT(priv->dragAndDropHandler); + priv->dragAndDropHandler->finishDrag(context); } -static void webkitWebViewBaseDragDataReceived(GtkWidget* widget, GdkDragContext* context, gint x, gint y, GtkSelectionData* selectionData, guint info, guint time) +static void webkitWebViewBaseDragDataReceived(GtkWidget* widget, GdkDragContext* context, gint /* x */, gint /* y */, GtkSelectionData* selectionData, guint info, guint time) { - WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - IntPoint position; - DataObjectGtk* dataObject = webViewBase->priv->dragAndDropHelper.handleDragDataReceived(context, selectionData, info, position); - if (!dataObject) - return; - - DragData dragData(dataObject, position, convertWidgetPointToScreenPoint(widget, position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context))); - webViewBase->priv->pageProxy->resetDragOperation(); - webViewBase->priv->pageProxy->dragEntered(dragData); - DragOperation operation = webViewBase->priv->pageProxy->dragSession().operation; - gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time); + webkitWebViewBaseDragAndDropHandler(WEBKIT_WEB_VIEW_BASE(widget)).dragEntered(context, selectionData, info, time); } #endif // ENABLE(DRAG_SUPPORT) @@ -839,57 +1059,38 @@ static AtkObject* webkitWebViewBaseGetAccessible(GtkWidget* widget) #if ENABLE(DRAG_SUPPORT) static gboolean webkitWebViewBaseDragMotion(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time) { - WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - IntPoint position(x, y); - DataObjectGtk* dataObject = webViewBase->priv->dragAndDropHelper.handleDragMotion(context, position, time); - if (!dataObject) - return TRUE; - - DragData dragData(dataObject, position, convertWidgetPointToScreenPoint(widget, position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context))); - webViewBase->priv->pageProxy->dragUpdated(dragData); - DragOperation operation = webViewBase->priv->pageProxy->dragSession().operation; - gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time); + webkitWebViewBaseDragAndDropHandler(WEBKIT_WEB_VIEW_BASE(widget)).dragMotion(context, IntPoint(x, y), time); return TRUE; } -static void dragExitedCallback(GtkWidget* widget, DragData& dragData, bool dropHappened) -{ - // Don't call dragExited if we have just received a drag-drop signal. This - // happens in the case of a successful drop onto the view. - if (dropHappened) - return; - - WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - webViewBase->priv->pageProxy->dragExited(dragData); - webViewBase->priv->pageProxy->resetDragOperation(); -} - -static void webkitWebViewBaseDragLeave(GtkWidget* widget, GdkDragContext* context, guint time) +static void webkitWebViewBaseDragLeave(GtkWidget* widget, GdkDragContext* context, guint /* time */) { - WEBKIT_WEB_VIEW_BASE(widget)->priv->dragAndDropHelper.handleDragLeave(context, dragExitedCallback); + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + ASSERT(priv->dragAndDropHandler); + priv->dragAndDropHandler->dragLeave(context); } static gboolean webkitWebViewBaseDragDrop(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time) { - WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - DataObjectGtk* dataObject = webViewBase->priv->dragAndDropHelper.handleDragDrop(context); - if (!dataObject) - return FALSE; - - IntPoint position(x, y); - DragData dragData(dataObject, position, convertWidgetPointToScreenPoint(widget, position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context))); - SandboxExtension::Handle handle; - SandboxExtension::HandleArray sandboxExtensionForUpload; - webViewBase->priv->pageProxy->performDrag(dragData, String(), handle, sandboxExtensionForUpload); - gtk_drag_finish(context, TRUE, FALSE, time); - return TRUE; + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + ASSERT(priv->dragAndDropHandler); + return priv->dragAndDropHandler->drop(context, IntPoint(x, y), time); } #endif // ENABLE(DRAG_SUPPORT) -static void webkitWebViewBaseParentSet(GtkWidget* widget, GtkWidget* oldParent) +static void webkitWebViewBaseHierarchyChanged(GtkWidget* widget, GtkWidget* oldToplevel) { - if (!gtk_widget_get_parent(widget)) - webkitWebViewBaseSetToplevelOnScreenWindow(WEBKIT_WEB_VIEW_BASE(widget), 0); + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + if (widgetIsOnscreenToplevelWindow(oldToplevel) && GTK_WINDOW(oldToplevel) == priv->toplevelOnScreenWindow) { + webkitWebViewBaseSetToplevelOnScreenWindow(WEBKIT_WEB_VIEW_BASE(widget), nullptr); + return; + } + + if (!oldToplevel) { + GtkWidget* toplevel = gtk_widget_get_toplevel(widget); + if (widgetIsOnscreenToplevelWindow(toplevel)) + webkitWebViewBaseSetToplevelOnScreenWindow(WEBKIT_WEB_VIEW_BASE(widget), GTK_WINDOW(toplevel)); + } } static gboolean webkitWebViewBaseFocus(GtkWidget* widget, GtkDirectionType direction) @@ -919,8 +1120,11 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie { GtkWidgetClass* widgetClass = GTK_WIDGET_CLASS(webkitWebViewBaseClass); widgetClass->realize = webkitWebViewBaseRealize; + widgetClass->unrealize = webkitWebViewBaseUnrealize; widgetClass->draw = webkitWebViewBaseDraw; widgetClass->size_allocate = webkitWebViewBaseSizeAllocate; + widgetClass->get_preferred_width = webkitWebViewBaseGetPreferredWidth; + widgetClass->get_preferred_height = webkitWebViewBaseGetPreferredHeight; widgetClass->map = webkitWebViewBaseMap; widgetClass->unmap = webkitWebViewBaseUnmap; widgetClass->focus = webkitWebViewBaseFocus; @@ -931,8 +1135,13 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie widgetClass->button_press_event = webkitWebViewBaseButtonPressEvent; widgetClass->button_release_event = webkitWebViewBaseButtonReleaseEvent; widgetClass->scroll_event = webkitWebViewBaseScrollEvent; + widgetClass->popup_menu = webkitWebViewBasePopupMenu; widgetClass->motion_notify_event = webkitWebViewBaseMotionNotifyEvent; + widgetClass->enter_notify_event = webkitWebViewBaseCrossingNotifyEvent; + widgetClass->leave_notify_event = webkitWebViewBaseCrossingNotifyEvent; +#if ENABLE(TOUCH_EVENTS) widgetClass->touch_event = webkitWebViewBaseTouchEvent; +#endif widgetClass->query_tooltip = webkitWebViewBaseQueryTooltip; #if ENABLE(DRAG_SUPPORT) widgetClass->drag_end = webkitWebViewBaseDragEnd; @@ -943,7 +1152,7 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie widgetClass->drag_data_received = webkitWebViewBaseDragDataReceived; #endif // ENABLE(DRAG_SUPPORT) widgetClass->get_accessible = webkitWebViewBaseGetAccessible; - widgetClass->parent_set = webkitWebViewBaseParentSet; + widgetClass->hierarchy_changed = webkitWebViewBaseHierarchyChanged; widgetClass->destroy = webkitWebViewBaseDestroy; GObjectClass* gobjectClass = G_OBJECT_CLASS(webkitWebViewBaseClass); @@ -954,12 +1163,17 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie containerClass->add = webkitWebViewBaseContainerAdd; containerClass->remove = webkitWebViewBaseContainerRemove; containerClass->forall = webkitWebViewBaseContainerForall; + + // Before creating a WebKitWebViewBasePriv we need to be sure that WebKit is started. + // Usually starting a context triggers InitializeWebKit2, but in case + // we create a view without asking before for a default_context we get a crash. + WebKit::InitializeWebKit2(); } -WebKitWebViewBase* webkitWebViewBaseCreate(WebContext* context, WebPageGroup* pageGroup, WebPageProxy* relatedPage) +WebKitWebViewBase* webkitWebViewBaseCreate(const API::PageConfiguration& configuration) { - WebKitWebViewBase* webkitWebViewBase = WEBKIT_WEB_VIEW_BASE(g_object_new(WEBKIT_TYPE_WEB_VIEW_BASE, NULL)); - webkitWebViewBaseCreateWebPage(webkitWebViewBase, context, pageGroup, relatedPage); + WebKitWebViewBase* webkitWebViewBase = WEBKIT_WEB_VIEW_BASE(g_object_new(WEBKIT_TYPE_WEB_VIEW_BASE, nullptr)); + webkitWebViewBaseCreateWebPage(webkitWebViewBase, configuration.copy()); return webkitWebViewBase; } @@ -973,18 +1187,6 @@ WebPageProxy* webkitWebViewBaseGetPage(WebKitWebViewBase* webkitWebViewBase) return webkitWebViewBase->priv->pageProxy.get(); } -void webkitWebViewBaseUpdatePreferences(WebKitWebViewBase* webkitWebViewBase) -{ - WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv; - -#if USE(TEXTURE_MAPPER_GL) - if (priv->redirectedWindow) - return; -#endif - - priv->pageProxy->pageGroup().preferences()->setAcceleratedCompositingEnabled(false); -} - #if HAVE(GTK_SCALE_FACTOR) static void deviceScaleFactorChanged(WebKitWebViewBase* webkitWebViewBase) { @@ -992,32 +1194,22 @@ static void deviceScaleFactorChanged(WebKitWebViewBase* webkitWebViewBase) } #endif // HAVE(GTK_SCALE_FACTOR) -void webkitWebViewBaseCreateWebPage(WebKitWebViewBase* webkitWebViewBase, WebContext* context, WebPageGroup* pageGroup, WebPageProxy* relatedPage) +void webkitWebViewBaseCreateWebPage(WebKitWebViewBase* webkitWebViewBase, Ref<API::PageConfiguration>&& configuration) { WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv; - - WebPageConfiguration webPageConfiguration; - webPageConfiguration.pageGroup = pageGroup; - webPageConfiguration.relatedPage = relatedPage; - priv->pageProxy = context->createWebPage(*priv->pageClient, std::move(webPageConfiguration)); + WebProcessPool* processPool = configuration->processPool(); + priv->pageProxy = processPool->createWebPage(*priv->pageClient, WTFMove(configuration)); priv->pageProxy->initializeWebPage(); -#if USE(TEXTURE_MAPPER_GL) - if (priv->redirectedWindow) - priv->pageProxy->setAcceleratedCompositingWindowId(priv->redirectedWindow->windowId()); -#endif + priv->acceleratedBackingStore = AcceleratedBackingStore::create(*priv->pageProxy); + + priv->inputMethodFilter.setPage(priv->pageProxy.get()); #if HAVE(GTK_SCALE_FACTOR) // We attach this here, because changes in scale factor are passed directly to the page proxy. priv->pageProxy->setIntrinsicDeviceScaleFactor(gtk_widget_get_scale_factor(GTK_WIDGET(webkitWebViewBase))); g_signal_connect(webkitWebViewBase, "notify::scale-factor", G_CALLBACK(deviceScaleFactorChanged), nullptr); #endif - - webkitWebViewBaseUpdatePreferences(webkitWebViewBase); - - // This must happen here instead of the instance initializer, because the input method - // filter must have access to the page. - priv->inputMethodFilter.setWebView(webkitWebViewBase); } void webkitWebViewBaseSetTooltipText(WebKitWebViewBase* webViewBase, const char* tooltip) @@ -1040,31 +1232,12 @@ void webkitWebViewBaseSetTooltipArea(WebKitWebViewBase* webViewBase, const IntRe } #if ENABLE(DRAG_SUPPORT) -void webkitWebViewBaseStartDrag(WebKitWebViewBase* webViewBase, const DragData& dragData, PassRefPtr<ShareableBitmap> dragImage) +DragAndDropHandler& webkitWebViewBaseDragAndDropHandler(WebKitWebViewBase* webViewBase) { WebKitWebViewBasePrivate* priv = webViewBase->priv; - - RefPtr<DataObjectGtk> dataObject = adoptRef(dragData.platformData()); - GRefPtr<GtkTargetList> targetList = adoptGRef(PasteboardHelper::defaultPasteboardHelper()->targetListForDataObject(dataObject.get())); - GUniquePtr<GdkEvent> currentEvent(gtk_get_current_event()); - GdkDragContext* context = gtk_drag_begin(GTK_WIDGET(webViewBase), - targetList.get(), - dragOperationToGdkDragActions(dragData.draggingSourceOperationMask()), - 1, /* button */ - currentEvent.get()); - priv->dragAndDropHelper.startedDrag(context, dataObject.get()); - - - // A drag starting should prevent a double-click from happening. This might - // happen if a drag is followed very quickly by another click (like in the DRT). - priv->clickCounter.reset(); - - if (dragImage) { - RefPtr<cairo_surface_t> image(dragImage->createCairoSurface()); - priv->dragIcon.setImage(image.get()); - priv->dragIcon.useForDrag(context); - } else - gtk_drag_set_icon_default(context); + if (!priv->dragAndDropHandler) + priv->dragAndDropHandler = std::make_unique<DragAndDropHandler>(*priv->pageProxy); + return *priv->dragAndDropHandler; } #endif // ENABLE(DRAG_SUPPORT) @@ -1073,6 +1246,80 @@ void webkitWebViewBaseForwardNextKeyEvent(WebKitWebViewBase* webkitWebViewBase) webkitWebViewBase->priv->shouldForwardNextKeyEvent = TRUE; } +void webkitWebViewBaseForwardNextWheelEvent(WebKitWebViewBase* webkitWebViewBase) +{ + webkitWebViewBase->priv->shouldForwardNextWheelEvent = true; +} + +#if ENABLE(FULLSCREEN_API) +static void screenSaverInhibitedCallback(GDBusProxy* screenSaverProxy, GAsyncResult* result, WebKitWebViewBase* webViewBase) +{ + GRefPtr<GVariant> returnValue = adoptGRef(g_dbus_proxy_call_finish(screenSaverProxy, result, nullptr)); + if (returnValue) + g_variant_get(returnValue.get(), "(u)", &webViewBase->priv->screenSaverCookie); + webViewBase->priv->screenSaverInhibitCancellable = nullptr; +} + +static void webkitWebViewBaseSendInhibitMessageToScreenSaver(WebKitWebViewBase* webViewBase) +{ + WebKitWebViewBasePrivate* priv = webViewBase->priv; + ASSERT(priv->screenSaverProxy); + priv->screenSaverCookie = 0; + if (!priv->screenSaverInhibitCancellable) + priv->screenSaverInhibitCancellable = adoptGRef(g_cancellable_new()); + g_dbus_proxy_call(priv->screenSaverProxy.get(), "Inhibit", g_variant_new("(ss)", g_get_prgname(), _("Website running in fullscreen mode")), + G_DBUS_CALL_FLAGS_NONE, -1, priv->screenSaverInhibitCancellable.get(), reinterpret_cast<GAsyncReadyCallback>(screenSaverInhibitedCallback), webViewBase); +} + +static void screenSaverProxyCreatedCallback(GObject*, GAsyncResult* result, WebKitWebViewBase* webViewBase) +{ + // WebKitWebViewBase cancels the proxy creation on dispose, which means this could be called + // after the web view has been destroyed and g_dbus_proxy_new_for_bus_finish will return nullptr. + // So, make sure we don't use the web view unless we have a valid proxy. + // See https://bugs.webkit.org/show_bug.cgi?id=151653. + GRefPtr<GDBusProxy> proxy = adoptGRef(g_dbus_proxy_new_for_bus_finish(result, nullptr)); + if (!proxy) + return; + + webViewBase->priv->screenSaverProxy = proxy; + webkitWebViewBaseSendInhibitMessageToScreenSaver(webViewBase); +} + +static void webkitWebViewBaseInhibitScreenSaver(WebKitWebViewBase* webViewBase) +{ + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (priv->screenSaverCookie) { + // Already inhibited. + return; + } + + if (priv->screenSaverProxy) { + webkitWebViewBaseSendInhibitMessageToScreenSaver(webViewBase); + return; + } + + priv->screenSaverInhibitCancellable = adoptGRef(g_cancellable_new()); + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION, static_cast<GDBusProxyFlags>(G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS), + nullptr, "org.freedesktop.ScreenSaver", "/ScreenSaver", "org.freedesktop.ScreenSaver", priv->screenSaverInhibitCancellable.get(), + reinterpret_cast<GAsyncReadyCallback>(screenSaverProxyCreatedCallback), webViewBase); +} + +static void webkitWebViewBaseUninhibitScreenSaver(WebKitWebViewBase* webViewBase) +{ + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (!priv->screenSaverCookie) { + // Not inhibited or it's being inhibited. + g_cancellable_cancel(priv->screenSaverInhibitCancellable.get()); + return; + } + + // If we have a cookie we should have a proxy. + ASSERT(priv->screenSaverProxy); + g_dbus_proxy_call(priv->screenSaverProxy.get(), "UnInhibit", g_variant_new("(u)", priv->screenSaverCookie), G_DBUS_CALL_FLAGS_NONE, -1, nullptr, nullptr, nullptr); + priv->screenSaverCookie = 0; +} +#endif + void webkitWebViewBaseEnterFullScreen(WebKitWebViewBase* webkitWebViewBase) { #if ENABLE(FULLSCREEN_API) @@ -1091,6 +1338,7 @@ void webkitWebViewBaseEnterFullScreen(WebKitWebViewBase* webkitWebViewBase) gtk_window_fullscreen(GTK_WINDOW(topLevelWindow)); fullScreenManagerProxy->didEnterFullScreen(); priv->fullScreenModeActive = true; + webkitWebViewBaseInhibitScreenSaver(webkitWebViewBase); #endif } @@ -1112,6 +1360,7 @@ void webkitWebViewBaseExitFullScreen(WebKitWebViewBase* webkitWebViewBase) gtk_window_unfullscreen(GTK_WINDOW(topLevelWindow)); fullScreenManagerProxy->didExitFullScreen(); priv->fullScreenModeActive = false; + webkitWebViewBaseUninhibitScreenSaver(webkitWebViewBase); #endif } @@ -1129,9 +1378,16 @@ void webkitWebViewBaseSetInspectorViewSize(WebKitWebViewBase* webkitWebViewBase, gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webkitWebViewBase)); } +static void activeContextMenuUnmapped(GtkMenu* menu, WebKitWebViewBase* webViewBase) +{ + if (webViewBase->priv->activeContextMenuProxy && webViewBase->priv->activeContextMenuProxy->gtkMenu() == menu) + webViewBase->priv->activeContextMenuProxy = nullptr; +} + void webkitWebViewBaseSetActiveContextMenuProxy(WebKitWebViewBase* webkitWebViewBase, WebContextMenuProxyGtk* contextMenuProxy) { webkitWebViewBase->priv->activeContextMenuProxy = contextMenuProxy; + g_signal_connect_object(contextMenuProxy->gtkMenu(), "unmap", G_CALLBACK(activeContextMenuUnmapped), webkitWebViewBase, static_cast<GConnectFlags>(0)); } WebContextMenuProxyGtk* webkitWebViewBaseGetActiveContextMenuProxy(WebKitWebViewBase* webkitWebViewBase) @@ -1144,57 +1400,49 @@ GdkEvent* webkitWebViewBaseTakeContextMenuEvent(WebKitWebViewBase* webkitWebView return webkitWebViewBase->priv->contextMenuEvent.release(); } -#if USE(TEXTURE_MAPPER_GL) -void redirectedWindowDamagedCallback(void* data) -{ - gtk_widget_queue_draw(GTK_WIDGET(data)); -} -#endif - void webkitWebViewBaseSetFocus(WebKitWebViewBase* webViewBase, bool focused) { WebKitWebViewBasePrivate* priv = webViewBase->priv; - if (priv->isFocused == focused) + if ((focused && priv->activityState & ActivityState::IsFocused) || (!focused && !(priv->activityState & ActivityState::IsFocused))) return; - unsigned viewStateFlags = ViewState::IsFocused; - priv->isFocused = focused; - - // If the view has received the focus and the window is not active - // mark the current window as active now. This can happen if the - // toplevel window is a GTK_WINDOW_POPUP and the focus has been - // set programatically like WebKitTestRunner does, because POPUP - // can't be focused. - if (priv->isFocused && !priv->isInWindowActive) { - priv->isInWindowActive = true; - viewStateFlags |= ViewState::WindowIsActive; - } - priv->pageProxy->viewStateDidChange(viewStateFlags); + ActivityState::Flags flagsToUpdate = ActivityState::IsFocused; + if (focused) { + priv->activityState |= ActivityState::IsFocused; + + // If the view has received the focus and the window is not active + // mark the current window as active now. This can happen if the + // toplevel window is a GTK_WINDOW_POPUP and the focus has been + // set programatically like WebKitTestRunner does, because POPUP + // can't be focused. + if (!(priv->activityState & ActivityState::WindowIsActive)) { + priv->activityState |= ActivityState::WindowIsActive; + flagsToUpdate |= ActivityState::WindowIsActive; + } + } else + priv->activityState &= ~ActivityState::IsFocused; + + webkitWebViewBaseScheduleUpdateActivityState(webViewBase, flagsToUpdate); } bool webkitWebViewBaseIsInWindowActive(WebKitWebViewBase* webViewBase) { - return webViewBase->priv->isInWindowActive; + return webViewBase->priv->activityState & ActivityState::WindowIsActive; } bool webkitWebViewBaseIsFocused(WebKitWebViewBase* webViewBase) { - return webViewBase->priv->isFocused; + return webViewBase->priv->activityState & ActivityState::IsFocused; } bool webkitWebViewBaseIsVisible(WebKitWebViewBase* webViewBase) { - return webViewBase->priv->isVisible; + return webViewBase->priv->activityState & ActivityState::IsVisible; } bool webkitWebViewBaseIsInWindow(WebKitWebViewBase* webViewBase) { - return webViewBase->priv->toplevelOnScreenWindow; -} - -bool webkitWebViewBaseIsWindowVisible(WebKitWebViewBase* webViewBase) -{ - return webViewBase->priv->isWindowVisible; + return webViewBase->priv->activityState & ActivityState::IsInWindow; } void webkitWebViewBaseSetDownloadRequestHandler(WebKitWebViewBase* webViewBase, WebKitWebViewBaseDownloadRequestHandler downloadHandler) @@ -1215,10 +1463,79 @@ void webkitWebViewBaseSetInputMethodState(WebKitWebViewBase* webkitWebViewBase, void webkitWebViewBaseUpdateTextInputState(WebKitWebViewBase* webkitWebViewBase) { - webkitWebViewBase->priv->inputMethodFilter.setCursorRect(webkitWebViewBase->priv->pageProxy->editorState().cursorRect); + const auto& editorState = webkitWebViewBase->priv->pageProxy->editorState(); + if (!editorState.isMissingPostLayoutData) + webkitWebViewBase->priv->inputMethodFilter.setCursorRect(editorState.postLayoutData().caretRectAtStart); +} + +void webkitWebViewBaseSetContentsSize(WebKitWebViewBase* webkitWebViewBase, const IntSize& contentsSize) +{ + WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv; + if (priv->contentsSize == contentsSize) + return; + priv->contentsSize = contentsSize; } void webkitWebViewBaseResetClickCounter(WebKitWebViewBase* webkitWebViewBase) { webkitWebViewBase->priv->clickCounter.reset(); } + +void webkitWebViewBaseEnterAcceleratedCompositingMode(WebKitWebViewBase* webkitWebViewBase, const LayerTreeContext& layerTreeContext) +{ + if (webkitWebViewBase->priv->acceleratedBackingStore) + webkitWebViewBase->priv->acceleratedBackingStore->update(layerTreeContext); +} + +void webkitWebViewBaseUpdateAcceleratedCompositingMode(WebKitWebViewBase* webkitWebViewBase, const LayerTreeContext& layerTreeContext) +{ + if (webkitWebViewBase->priv->acceleratedBackingStore) + webkitWebViewBase->priv->acceleratedBackingStore->update(layerTreeContext); +} + +void webkitWebViewBaseExitAcceleratedCompositingMode(WebKitWebViewBase* webkitWebViewBase) +{ + if (webkitWebViewBase->priv->acceleratedBackingStore) + webkitWebViewBase->priv->acceleratedBackingStore->update(LayerTreeContext()); +} + +void webkitWebViewBaseDidRelaunchWebProcess(WebKitWebViewBase* webkitWebViewBase) +{ + // Queue a resize to ensure the new DrawingAreaProxy is resized. + gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webkitWebViewBase)); + +#if PLATFORM(X11) && USE(TEXTURE_MAPPER_GL) && !USE(REDIRECTED_XCOMPOSITE_WINDOW) + if (PlatformDisplay::sharedDisplay().type() != PlatformDisplay::Type::X11) + return; + + WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv; + DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(priv->pageProxy->drawingArea()); + ASSERT(drawingArea); + + if (!gtk_widget_get_realized(GTK_WIDGET(webkitWebViewBase))) + return; + + uint64_t windowID = GDK_WINDOW_XID(gtk_widget_get_window(GTK_WIDGET(webkitWebViewBase))); + drawingArea->setNativeSurfaceHandleForCompositing(windowID); +#else + UNUSED_PARAM(webkitWebViewBase); +#endif +} + +void webkitWebViewBasePageClosed(WebKitWebViewBase* webkitWebViewBase) +{ + if (webkitWebViewBase->priv->acceleratedBackingStore) + webkitWebViewBase->priv->acceleratedBackingStore->update(LayerTreeContext()); +#if PLATFORM(X11) && USE(TEXTURE_MAPPER_GL) && !USE(REDIRECTED_XCOMPOSITE_WINDOW) + if (PlatformDisplay::sharedDisplay().type() != PlatformDisplay::Type::X11) + return; + + if (!gtk_widget_get_realized(GTK_WIDGET(webkitWebViewBase))) + return; + + WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv; + DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(priv->pageProxy->drawingArea()); + ASSERT(drawingArea); + drawingArea->destroyNativeSurfaceHandleForCompositing(); +#endif +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBaseAccessible.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBaseAccessible.cpp index 7b069dd94..fc2d053a7 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBaseAccessible.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBaseAccessible.cpp @@ -29,7 +29,7 @@ struct _WebKitWebViewBaseAccessiblePrivate { WEBKIT_DEFINE_TYPE(WebKitWebViewBaseAccessible, webkit_web_view_base_accessible, ATK_TYPE_SOCKET) -static void webkitWebViewBaseAccessibleWidgetDestroyed(GtkWidget* widget, WebKitWebViewBaseAccessible* accessible) +static void webkitWebViewBaseAccessibleWidgetDestroyed(GtkWidget*, WebKitWebViewBaseAccessible* accessible) { accessible->priv->widget = 0; atk_object_notify_state_change(ATK_OBJECT(accessible), ATK_STATE_DEFUNCT, TRUE); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h index b9c38c265..6f5ba9d02 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h @@ -28,20 +28,23 @@ #ifndef WebKitWebViewBasePrivate_h #define WebKitWebViewBasePrivate_h +#include "APIPageConfiguration.h" +#include "DragAndDropHandler.h" +#include "GestureController.h" #include "WebContextMenuProxyGtk.h" #include "WebInspectorProxy.h" #include "WebKitPrivate.h" #include "WebKitWebViewBase.h" #include "WebPageProxy.h" -WebKitWebViewBase* webkitWebViewBaseCreate(WebKit::WebContext*, WebKit::WebPageGroup*, WebKit::WebPageProxy*); +WebKitWebViewBase* webkitWebViewBaseCreate(const API::PageConfiguration&); GtkIMContext* webkitWebViewBaseGetIMContext(WebKitWebViewBase*); WebKit::WebPageProxy* webkitWebViewBaseGetPage(WebKitWebViewBase*); -void webkitWebViewBaseCreateWebPage(WebKitWebViewBase*, WebKit::WebContext*, WebKit::WebPageGroup*, WebKit::WebPageProxy*); +void webkitWebViewBaseCreateWebPage(WebKitWebViewBase*, Ref<API::PageConfiguration>&&); void webkitWebViewBaseSetTooltipText(WebKitWebViewBase*, const char*); void webkitWebViewBaseSetTooltipArea(WebKitWebViewBase*, const WebCore::IntRect&); void webkitWebViewBaseForwardNextKeyEvent(WebKitWebViewBase*); -void webkitWebViewBaseStartDrag(WebKitWebViewBase*, const WebCore::DragData&, PassRefPtr<WebKit::ShareableBitmap> dragImage); +void webkitWebViewBaseForwardNextWheelEvent(WebKitWebViewBase*); void webkitWebViewBaseChildMoveResize(WebKitWebViewBase*, GtkWidget*, const WebCore::IntRect&); void webkitWebViewBaseEnterFullScreen(WebKitWebViewBase*); void webkitWebViewBaseExitFullScreen(WebKitWebViewBase*); @@ -52,18 +55,13 @@ WebKit::WebContextMenuProxyGtk* webkitWebViewBaseGetActiveContextMenuProxy(WebKi GdkEvent* webkitWebViewBaseTakeContextMenuEvent(WebKitWebViewBase*); void webkitWebViewBaseSetInputMethodState(WebKitWebViewBase*, bool enabled); void webkitWebViewBaseUpdateTextInputState(WebKitWebViewBase*); -void webkitWebViewBaseUpdatePreferences(WebKitWebViewBase*); - -#if USE(TEXTURE_MAPPER_GL) -void webkitWebViewBaseQueueDrawOfAcceleratedCompositingResults(WebKitWebViewBase*); -#endif +void webkitWebViewBaseSetContentsSize(WebKitWebViewBase*, const WebCore::IntSize&); void webkitWebViewBaseSetFocus(WebKitWebViewBase*, bool focused); bool webkitWebViewBaseIsInWindowActive(WebKitWebViewBase*); bool webkitWebViewBaseIsFocused(WebKitWebViewBase*); bool webkitWebViewBaseIsVisible(WebKitWebViewBase*); bool webkitWebViewBaseIsInWindow(WebKitWebViewBase*); -bool webkitWebViewBaseIsWindowVisible(WebKitWebViewBase*); typedef void (*WebKitWebViewBaseDownloadRequestHandler) (WebKitWebViewBase*, WebKit::DownloadProxy*); void webkitWebViewBaseSetDownloadRequestHandler(WebKitWebViewBase*, WebKitWebViewBaseDownloadRequestHandler); @@ -73,5 +71,18 @@ void webkitWebViewBaseAddAuthenticationDialog(WebKitWebViewBase*, GtkWidget* aut void webkitWebViewBaseCancelAuthenticationDialog(WebKitWebViewBase*); void webkitWebViewBaseAddWebInspector(WebKitWebViewBase*, GtkWidget* inspector, WebKit::AttachmentSide); void webkitWebViewBaseResetClickCounter(WebKitWebViewBase*); +void webkitWebViewBaseEnterAcceleratedCompositingMode(WebKitWebViewBase*, const WebKit::LayerTreeContext&); +void webkitWebViewBaseUpdateAcceleratedCompositingMode(WebKitWebViewBase*, const WebKit::LayerTreeContext&); +void webkitWebViewBaseExitAcceleratedCompositingMode(WebKitWebViewBase*); +void webkitWebViewBaseDidRelaunchWebProcess(WebKitWebViewBase*); +void webkitWebViewBasePageClosed(WebKitWebViewBase*); + +#if ENABLE(DRAG_SUPPORT) +WebKit::DragAndDropHandler& webkitWebViewBaseDragAndDropHandler(WebKitWebViewBase*); +#endif + +#if HAVE(GTK_GESTURES) +WebKit::GestureController& webkitWebViewBaseGestureController(WebKitWebViewBase*); +#endif #endif // WebKitWebViewBasePrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.cpp deleted file mode 100644 index 289ecdf03..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.cpp +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (C) 2013 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "WebKitWebViewGroup.h" - -#include "APIArray.h" -#include "APIString.h" -#include "WebKitPrivate.h" -#include "WebKitSettingsPrivate.h" -#include "WebKitWebViewGroupPrivate.h" -#include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/text/CString.h> - -using namespace WebKit; - -/** - * SECTION: WebKitWebViewGroup - * @Short_description: Group of web views - * @Title: WebKitWebViewGroup - * @See_also: #WebKitWebView, #WebKitSettings - * - * A WebKitWebViewGroup represents a group of #WebKitWebView<!-- -->s that - * share things like settings. There's a default WebKitWebViewGroup where - * all #WebKitWebView<!-- -->s of the same #WebKitWebContext are added by default. - * To create a #WebKitWebView in a different WebKitWebViewGroup you can use - * webkit_web_view_new_with_group(). - * - * WebKitWebViewGroups are identified by a unique name given when the group is - * created with webkit_web_view_group_new(). - * WebKitWebViewGroups have a #WebKitSettings to control the settings of all - * #WebKitWebView<!-- -->s of the group. You can get the settings with - * webkit_web_view_group_get_settings() to handle the settings, or you can set - * your own #WebKitSettings with webkit_web_view_group_set_settings(). When - * the #WebKitSettings of a WebKitWebViewGroup changes, the signal notify::settings - * is emitted on the group. - */ - -enum { - PROP_0, - - PROP_SETTINGS -}; - -struct _WebKitWebViewGroupPrivate { - RefPtr<WebPageGroup> pageGroup; - CString name; - GRefPtr<WebKitSettings> settings; -}; - -WEBKIT_DEFINE_TYPE(WebKitWebViewGroup, webkit_web_view_group, G_TYPE_OBJECT) - -static void webkitWebViewGroupSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) -{ - WebKitWebViewGroup* group = WEBKIT_WEB_VIEW_GROUP(object); - - switch (propId) { - case PROP_SETTINGS: - webkit_web_view_group_set_settings(group, WEBKIT_SETTINGS(g_value_get_object(value))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); - } -} - -static void webkitWebViewGroupGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) -{ - WebKitWebViewGroup* group = WEBKIT_WEB_VIEW_GROUP(object); - - switch (propId) { - case PROP_SETTINGS: - g_value_set_object(value, webkit_web_view_group_get_settings(group)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); - } -} - -static void webkitWebViewGroupConstructed(GObject* object) -{ - G_OBJECT_CLASS(webkit_web_view_group_parent_class)->constructed(object); - - WebKitWebViewGroupPrivate* priv = WEBKIT_WEB_VIEW_GROUP(object)->priv; - priv->settings = adoptGRef(webkit_settings_new()); -} - -static void webkit_web_view_group_class_init(WebKitWebViewGroupClass* hitTestResultClass) -{ - GObjectClass* objectClass = G_OBJECT_CLASS(hitTestResultClass); - objectClass->set_property = webkitWebViewGroupSetProperty; - objectClass->get_property = webkitWebViewGroupGetProperty; - objectClass->constructed = webkitWebViewGroupConstructed; - - /** - * WebKitWebViewGroup:settings: - * - * The #WebKitSettings of the web view group. - */ - g_object_class_install_property( - objectClass, - PROP_SETTINGS, - g_param_spec_object( - "settings", - _("Settings"), - _("The settings of the web view group"), - WEBKIT_TYPE_SETTINGS, - WEBKIT_PARAM_READWRITE)); -} - -static void webkitWebViewGroupAttachSettingsToPageGroup(WebKitWebViewGroup* group) -{ - group->priv->pageGroup->setPreferences(webkitSettingsGetPreferences(group->priv->settings.get())); -} - -WebKitWebViewGroup* webkitWebViewGroupCreate(WebPageGroup* pageGroup) -{ - WebKitWebViewGroup* group = WEBKIT_WEB_VIEW_GROUP(g_object_new(WEBKIT_TYPE_WEB_VIEW_GROUP, NULL)); - group->priv->pageGroup = pageGroup; - webkitWebViewGroupAttachSettingsToPageGroup(group); - return group; -} - -WebPageGroup* webkitWebViewGroupGetPageGroup(WebKitWebViewGroup* group) -{ - return group->priv->pageGroup.get(); -} - -/** - * webkit_web_view_group_new: - * @name: (allow-none): the name of the group - * - * Creates a new #WebKitWebViewGroup with the given @name. - * If @name is %NULL a unique identifier name will be created - * automatically. - * The newly created #WebKitWebViewGroup doesn't contain any - * #WebKitWebView, web views are added to the new group when created - * with webkit_web_view_new_with_group() passing the group. - * - * Returns: (transfer full): a new #WebKitWebViewGroup - */ -WebKitWebViewGroup* webkit_web_view_group_new(const char* name) -{ - WebKitWebViewGroup* group = WEBKIT_WEB_VIEW_GROUP(g_object_new(WEBKIT_TYPE_WEB_VIEW_GROUP, NULL)); - group->priv->pageGroup = WebPageGroup::create(name ? String::fromUTF8(name) : String()); - webkitWebViewGroupAttachSettingsToPageGroup(group); - return group; -} - -/** - * webkit_web_view_group_get_name: - * @group: a #WebKitWebViewGroup - * - * Gets the name that uniquely identifies the #WebKitWebViewGroup. - * - * Returns: the name of @group - */ -const char* webkit_web_view_group_get_name(WebKitWebViewGroup* group) -{ - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group), 0); - - WebKitWebViewGroupPrivate* priv = group->priv; - if (priv->name.isNull()) - priv->name = priv->pageGroup->identifier().utf8(); - - return priv->name.data(); -} - -/** - * webkit_web_view_group_get_settings: - * @group: a #WebKitWebViewGroup - * - * Gets the #WebKitSettings of the #WebKitWebViewGroup. - * - * Returns: (transfer none): the settings of @group - */ -WebKitSettings* webkit_web_view_group_get_settings(WebKitWebViewGroup* group) -{ - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group), 0); - - return group->priv->settings.get(); -} - -/** - * webkit_web_view_group_set_settings: - * @group: a #WebKitWebViewGroup - * @settings: a #WebKitSettings - * - * Sets a new #WebKitSettings for the #WebKitWebViewGroup. The settings will - * affect to all the #WebKitWebView<!-- -->s of the group. - * #WebKitWebViewGroup<!-- -->s always have a #WebKitSettings so if you just want to - * modify a setting you can use webkit_web_view_group_get_settings() and modify the - * returned #WebKitSettings instead. - * Setting the same #WebKitSettings multiple times doesn't have any effect. - * You can monitor the settings of a #WebKitWebViewGroup by connecting to the - * notify::settings signal of @group. - */ -void webkit_web_view_group_set_settings(WebKitWebViewGroup* group, WebKitSettings* settings) -{ - g_return_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group)); - g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); - - if (group->priv->settings == settings) - return; - - group->priv->settings = settings; - webkitWebViewGroupAttachSettingsToPageGroup(group); - g_object_notify(G_OBJECT(group), "settings"); -} - -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_INJECTED_CONTENT_FRAMES_ALL, WebCore::InjectInAllFrames); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_INJECTED_CONTENT_FRAMES_TOP_ONLY, WebCore::InjectInTopFrameOnly); - -static PassRefPtr<API::Array> toAPIArray(const char* const* list) -{ - if (!list) - return 0; - - Vector<RefPtr<API::Object> > entries; - while (*list) { - entries.append(API::String::createFromUTF8String(*list)); - list++; - } - return API::Array::create(std::move(entries)); -} - -/** - * webkit_web_view_group_add_user_style_sheet: - * @group: a #WebKitWebViewGroup - * @source: the source of the style_sheet to inject - * @base_uri: (allow-none): the base URI to use when processing the style_sheet contents or %NULL for about:blank - * @whitelist: (array zero-terminated=1) (allow-none): a whitelist of URI patterns or %NULL - * @blacklist: (array zero-terminated=1) (allow-none): a blacklist of URI patterns or %NULL - * @injected_frames: a #WebKitInjectedContentFrames describing to which frames the style_sheet should apply - * - * Inject an external style sheet into pages. It is possible to only apply the style sheet - * to some URIs by passing non-null values for @whitelist or @blacklist. Passing a %NULL - * whitelist implies that all URIs are on the whitelist. The style sheet is applied if a URI matches - * the whitelist and not the blacklist. URI patterns must be of the form [protocol]://[host]/[path] - * where the host and path components can contain the wildcard character ('*') to represent zero - * or more other characters. - */ -void webkit_web_view_group_add_user_style_sheet(WebKitWebViewGroup* group, const char* source, const char* baseURI, const char* const* whitelist, const char* const* blacklist, WebKitInjectedContentFrames injectedFrames) -{ - g_return_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group)); - g_return_if_fail(source); - - RefPtr<API::Array> webWhitelist = toAPIArray(whitelist); - RefPtr<API::Array> webBlacklist = toAPIArray(blacklist); - - // We always use UserStyleUserLevel to match the behavior of WKPageGroupAddUserStyleSheet. - group->priv->pageGroup->addUserStyleSheet( - String::fromUTF8(source), - String::fromUTF8(baseURI), - webWhitelist.get(), - webBlacklist.get(), - static_cast<WebCore::UserContentInjectedFrames>(injectedFrames), - WebCore::UserStyleUserLevel); -} - -/** - * webkit_web_view_group_remove_all_user_style_sheets: - * @group: a #WebKitWebViewGroup - * - * Remove all style sheets previously injected into this #WebKitWebViewGroup - * via webkit_web_view_group_add_user_style_sheet(). - */ -void webkit_web_view_group_remove_all_user_style_sheets(WebKitWebViewGroup* group) -{ - g_return_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group)); - group->priv->pageGroup->removeAllUserStyleSheets(); -} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.h deleted file mode 100644 index 685f19904..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2013 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) -#error "Only <webkit2/webkit2.h> can be included directly." -#endif - -#ifndef WebKitWebViewGroup_h -#define WebKitWebViewGroup_h - -#include <glib-object.h> -#include <webkit2/WebKitDefines.h> -#include <webkit2/WebKitSettings.h> - -G_BEGIN_DECLS - -#define WEBKIT_TYPE_WEB_VIEW_GROUP (webkit_web_view_group_get_type()) -#define WEBKIT_WEB_VIEW_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_WEB_VIEW_GROUP, WebKitWebViewGroup)) -#define WEBKIT_IS_WEB_VIEW_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_WEB_VIEW_GROUP)) -#define WEBKIT_WEB_VIEW_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_WEB_VIEW_GROUP, WebKitWebViewGroupClass)) -#define WEBKIT_IS_WEB_VIEW_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_WEB_VIEW_GROUP)) -#define WEBKIT_WEB_VIEW_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_WEB_VIEW_GROUP, WebKitWebViewGroupClass)) - -typedef struct _WebKitWebViewGroup WebKitWebViewGroup; -typedef struct _WebKitWebViewGroupClass WebKitWebViewGroupClass; -typedef struct _WebKitWebViewGroupPrivate WebKitWebViewGroupPrivate; - -struct _WebKitWebViewGroup { - GObject parent; - - WebKitWebViewGroupPrivate *priv; -}; - -struct _WebKitWebViewGroupClass { - GObjectClass parent_class; - - void (*_webkit_reserved0) (void); - void (*_webkit_reserved1) (void); - void (*_webkit_reserved2) (void); - void (*_webkit_reserved3) (void); -}; - -/** - * WebKitInjectedContentFrames: - * @WEBKIT_INJECTED_CONTENT_FRAMES_ALL: Content will be injected into all frames. - * @WEBKIT_INJECTED_CONTENT_FRAMES_TOP_ONLY: Content will only be injected into the main frame. - * - * Enum values used for determining into which frames content is injected. - */ -typedef enum { - WEBKIT_INJECTED_CONTENT_FRAMES_ALL, - WEBKIT_INJECTED_CONTENT_FRAMES_TOP_ONLY, -} WebKitInjectedContentFrames; - -WEBKIT_API GType -webkit_web_view_group_get_type (void); - -WEBKIT_API WebKitWebViewGroup * -webkit_web_view_group_new (const gchar *name); - -WEBKIT_API const gchar * -webkit_web_view_group_get_name (WebKitWebViewGroup *group); - -WEBKIT_API WebKitSettings * -webkit_web_view_group_get_settings (WebKitWebViewGroup *group); - -WEBKIT_API void -webkit_web_view_group_set_settings (WebKitWebViewGroup *group, - WebKitSettings *settings); - -WEBKIT_API void -webkit_web_view_group_add_user_style_sheet (WebKitWebViewGroup *group, - const gchar *source, - const gchar *base_uri, - const gchar * const *whitelist, - const gchar * const *blacklist, - WebKitInjectedContentFrames injected_frames); - -WEBKIT_API void -webkit_web_view_group_remove_all_user_style_sheets (WebKitWebViewGroup *group); - -G_END_DECLS - -#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h index 11591ff18..240d73088 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h @@ -27,6 +27,9 @@ #ifndef WebKitWebViewPrivate_h #define WebKitWebViewPrivate_h +#include "InstallMissingMediaPluginsPermissionRequest.h" +#include "WebContextMenuItemData.h" +#include "WebHitTestResultData.h" #include "WebImage.h" #include "WebKitWebView.h" #include <wtf/text/CString.h> @@ -34,19 +37,17 @@ void webkitWebViewLoadChanged(WebKitWebView*, WebKitLoadEvent); void webkitWebViewLoadFailed(WebKitWebView*, WebKitLoadEvent, const char* failingURI, GError*); void webkitWebViewLoadFailedWithTLSErrors(WebKitWebView*, const char* failingURI, GError*, GTlsCertificateFlags, GTlsCertificate*); -void webkitWebViewSetEstimatedLoadProgress(WebKitWebView*, double estimatedLoadProgress); -void webkitWebViewSetTitle(WebKitWebView*, const CString&); -void webkitWebViewUpdateURI(WebKitWebView*); -WebKit::WebPageProxy* webkitWebViewCreateNewPage(WebKitWebView*, WebKit::ImmutableDictionary* windowFeatures); +WebKit::WebPageProxy* webkitWebViewCreateNewPage(WebKitWebView*, const WebCore::WindowFeatures&, WebKitNavigationAction*); void webkitWebViewReadyToShowPage(WebKitWebView*); void webkitWebViewRunAsModal(WebKitWebView*); void webkitWebViewClosePage(WebKitWebView*); void webkitWebViewRunJavaScriptAlert(WebKitWebView*, const CString& message); bool webkitWebViewRunJavaScriptConfirm(WebKitWebView*, const CString& message); CString webkitWebViewRunJavaScriptPrompt(WebKitWebView*, const CString& message, const CString& defaultText); +bool webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView*, const CString& message); void webkitWebViewMakePermissionRequest(WebKitWebView*, WebKitPermissionRequest*); void webkitWebViewMakePolicyDecision(WebKitWebView*, WebKitPolicyDecisionType, WebKitPolicyDecision*); -void webkitWebViewMouseTargetChanged(WebKitWebView*, WebKit::WebHitTestResult*, unsigned modifiers); +void webkitWebViewMouseTargetChanged(WebKitWebView*, const WebKit::WebHitTestResultData&, unsigned modifiers); void webkitWebViewPrintFrame(WebKitWebView*, WebKit::WebFrameProxy*); void webkitWebViewResourceLoadStarted(WebKitWebView*, WebKit::WebFrameProxy*, uint64_t resourceIdentifier, WebKitURIRequest*); void webkitWebViewRunFileChooserRequest(WebKitWebView*, WebKitFileChooserRequest*); @@ -55,10 +56,16 @@ void webKitWebViewDidReceiveSnapshot(WebKitWebView*, uint64_t callbackID, WebKit void webkitWebViewRemoveLoadingWebResource(WebKitWebView*, uint64_t resourceIdentifier); bool webkitWebViewEnterFullScreen(WebKitWebView*); bool webkitWebViewLeaveFullScreen(WebKitWebView*); -void webkitWebViewPopulateContextMenu(WebKitWebView*, API::Array* proposedMenu, WebKit::WebHitTestResult*); +void webkitWebViewPopulateContextMenu(WebKitWebView*, const Vector<WebKit::WebContextMenuItemData>& proposedMenu, const WebKit::WebHitTestResultData&, GVariant*); void webkitWebViewSubmitFormRequest(WebKitWebView*, WebKitFormSubmissionRequest*); void webkitWebViewHandleAuthenticationChallenge(WebKitWebView*, WebKit::AuthenticationChallengeProxy*); void webkitWebViewInsecureContentDetected(WebKitWebView*, WebKitInsecureContentEvent); +bool webkitWebViewEmitShowNotification(WebKitWebView*, WebKitNotification*); +bool webkitWebViewEmitRunColorChooser(WebKitWebView*, WebKitColorChooserRequest*); void webkitWebViewWebProcessCrashed(WebKitWebView*); +void webkitWebViewIsPlayingAudioChanged(WebKitWebView*); +void webkitWebViewSelectionDidChange(WebKitWebView*); +void webkitWebViewRequestInstallMissingMediaPlugins(WebKitWebView*, WebKit::InstallMissingMediaPluginsPermissionRequest&); +WebKitWebsiteDataManager* webkitWebViewGetWebsiteDataManager(WebKitWebView*); #endif // WebKitWebViewPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionState.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionState.cpp new file mode 100644 index 000000000..325d0141c --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionState.cpp @@ -0,0 +1,461 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitWebViewSessionState.h" + +#include "WebKitWebViewSessionStatePrivate.h" +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> + +using namespace WebKit; + +struct _WebKitWebViewSessionState { + _WebKitWebViewSessionState(SessionState&& state) + : sessionState(WTFMove(state)) + , referenceCount(1) + { + } + + SessionState sessionState; + int referenceCount; +}; + +G_DEFINE_BOXED_TYPE(WebKitWebViewSessionState, webkit_web_view_session_state, webkit_web_view_session_state_ref, webkit_web_view_session_state_unref) + +static const guint16 g_sessionStateVersion = 1; +#define HTTP_BODY_ELEMENT_TYPE_STRING_V1 "(uaysxmxmds)" +#define HTTP_BODY_ELEMENT_FORMAT_STRING_V1 "(uay&sxmxmd&s)" +#define HTTP_BODY_TYPE_STRING_V1 "m(sa" HTTP_BODY_ELEMENT_TYPE_STRING_V1 ")" +#define HTTP_BODY_FORMAT_STRING_V1 "m(&sa" HTTP_BODY_ELEMENT_TYPE_STRING_V1 ")" +#define FRAME_STATE_TYPE_STRING_V1 "(ssssasmayxx(ii)d" HTTP_BODY_TYPE_STRING_V1 "av)" +#define FRAME_STATE_FORMAT_STRING_V1 "(&s&s&s&sasmayxx(ii)d@" HTTP_BODY_TYPE_STRING_V1 "av)" +#define BACK_FORWARD_LIST_ITEM_TYPE_STRING_V1 "(ts" FRAME_STATE_TYPE_STRING_V1 "u)" +#define BACK_FORWARD_LIST_ITEM_FORMAT_STRING_V1 "(t&s@" FRAME_STATE_TYPE_STRING_V1 "u)" +#define SESSION_STATE_TYPE_STRING_V1 "(qa" BACK_FORWARD_LIST_ITEM_TYPE_STRING_V1 "mu)" + +// Use our own enum types to ensure the serialized format even if the core enums change. +enum ExternalURLsPolicy { + Allow, + AllowExternalSchemes, + NotAllow +}; + +static inline unsigned toExternalURLsPolicy(WebCore::ShouldOpenExternalURLsPolicy policy) +{ + switch (policy) { + case WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow: + return ExternalURLsPolicy::Allow; + case WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes: + return ExternalURLsPolicy::AllowExternalSchemes; + case WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow: + return ExternalURLsPolicy::NotAllow; + } + + return ExternalURLsPolicy::NotAllow; +} + +static inline WebCore::ShouldOpenExternalURLsPolicy toWebCoreExternalURLsPolicy(unsigned policy) +{ + switch (policy) { + case ExternalURLsPolicy::Allow: + return WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow; + case ExternalURLsPolicy::AllowExternalSchemes: + return WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes; + case ExternalURLsPolicy::NotAllow: + return WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow; + } + + return WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow; +} + +enum HTMLBodyElementType { + Data, + File, + Blob +}; + +static inline unsigned toHTMLBodyElementType(HTTPBody::Element::Type type) +{ + switch (type) { + case HTTPBody::Element::Type::Data: + return HTMLBodyElementType::Data; + case HTTPBody::Element::Type::File: + return HTMLBodyElementType::File; + case HTTPBody::Element::Type::Blob: + return HTMLBodyElementType::Blob; + } + + return HTMLBodyElementType::Data; +} + +static inline HTTPBody::Element::Type toHTTPBodyElementType(unsigned type) +{ + switch (type) { + case HTMLBodyElementType::Data: + return HTTPBody::Element::Type::Data; + case HTMLBodyElementType::File: + return HTTPBody::Element::Type::File; + case HTMLBodyElementType::Blob: + return HTTPBody::Element::Type::Blob; + } + + return HTTPBody::Element::Type::Data; +} + +static inline void encodeHTTPBody(GVariantBuilder* sessionBuilder, const HTTPBody& httpBody) +{ + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("(sa" HTTP_BODY_ELEMENT_TYPE_STRING_V1 ")")); + g_variant_builder_add(sessionBuilder, "s", httpBody.contentType.utf8().data()); + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("a" HTTP_BODY_ELEMENT_TYPE_STRING_V1)); + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE(HTTP_BODY_ELEMENT_TYPE_STRING_V1)); + for (const auto& element : httpBody.elements) { + g_variant_builder_add(sessionBuilder, "u", toHTMLBodyElementType(element.type)); + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("ay")); + for (auto item : element.data) + g_variant_builder_add(sessionBuilder, "y", item); + g_variant_builder_close(sessionBuilder); + g_variant_builder_add(sessionBuilder, "s", element.filePath.utf8().data()); + g_variant_builder_add(sessionBuilder, "x", element.fileStart); + if (element.fileLength) + g_variant_builder_add(sessionBuilder, "mx", TRUE, element.fileLength.value()); + else + g_variant_builder_add(sessionBuilder, "mx", FALSE); + if (element.expectedFileModificationTime) + g_variant_builder_add(sessionBuilder, "md", TRUE, element.expectedFileModificationTime.value()); + else + g_variant_builder_add(sessionBuilder, "md", FALSE); + g_variant_builder_add(sessionBuilder, "s", element.blobURLString.utf8().data()); + } + g_variant_builder_close(sessionBuilder); + g_variant_builder_close(sessionBuilder); + g_variant_builder_close(sessionBuilder); +} + +static inline void encodeFrameState(GVariantBuilder* sessionBuilder, const FrameState& frameState) +{ + g_variant_builder_add(sessionBuilder, "s", frameState.urlString.utf8().data()); + g_variant_builder_add(sessionBuilder, "s", frameState.originalURLString.utf8().data()); + g_variant_builder_add(sessionBuilder, "s", frameState.referrer.utf8().data()); + g_variant_builder_add(sessionBuilder, "s", frameState.target.utf8().data()); + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("as")); + for (const auto& state : frameState.documentState) + g_variant_builder_add(sessionBuilder, "s", state.utf8().data()); + g_variant_builder_close(sessionBuilder); + if (!frameState.stateObjectData) + g_variant_builder_add(sessionBuilder, "may", FALSE); + else { + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("may")); + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("ay")); + for (auto item : frameState.stateObjectData.value()) + g_variant_builder_add(sessionBuilder, "y", item); + g_variant_builder_close(sessionBuilder); + g_variant_builder_close(sessionBuilder); + } + g_variant_builder_add(sessionBuilder, "x", frameState.documentSequenceNumber); + g_variant_builder_add(sessionBuilder, "x", frameState.itemSequenceNumber); + g_variant_builder_add(sessionBuilder, "(ii)", frameState.scrollPosition.x(), frameState.scrollPosition.y()); + g_variant_builder_add(sessionBuilder, "d", frameState.pageScaleFactor); + if (!frameState.httpBody) + g_variant_builder_add(sessionBuilder, HTTP_BODY_TYPE_STRING_V1, FALSE); + else { + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE(HTTP_BODY_TYPE_STRING_V1)); + encodeHTTPBody(sessionBuilder, frameState.httpBody.value()); + g_variant_builder_close(sessionBuilder); + } + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("av")); + for (const auto& child : frameState.children) { + GVariantBuilder frameStateBuilder; + g_variant_builder_init(&frameStateBuilder, G_VARIANT_TYPE(FRAME_STATE_TYPE_STRING_V1)); + encodeFrameState(&frameStateBuilder, child); + g_variant_builder_add(sessionBuilder, "v", g_variant_builder_end(&frameStateBuilder)); + } + g_variant_builder_close(sessionBuilder); +} + +static inline void encodePageState(GVariantBuilder* sessionBuilder, const PageState& pageState) +{ + g_variant_builder_add(sessionBuilder, "s", pageState.title.utf8().data()); + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE(FRAME_STATE_TYPE_STRING_V1)); + encodeFrameState(sessionBuilder, pageState.mainFrameState); + g_variant_builder_close(sessionBuilder); + g_variant_builder_add(sessionBuilder, "u", toExternalURLsPolicy(pageState.shouldOpenExternalURLsPolicy)); +} + +static inline void encodeBackForwardListItemState(GVariantBuilder* sessionBuilder, const BackForwardListItemState& item) +{ + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE(BACK_FORWARD_LIST_ITEM_TYPE_STRING_V1)); + g_variant_builder_add(sessionBuilder, "t", item.identifier); + encodePageState(sessionBuilder, item.pageState); + g_variant_builder_close(sessionBuilder); +} + +static inline void encodeBackForwardListState(GVariantBuilder* sessionBuilder, const BackForwardListState& backForwardListState) +{ + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("a" BACK_FORWARD_LIST_ITEM_TYPE_STRING_V1)); + for (const auto& item : backForwardListState.items) + encodeBackForwardListItemState(sessionBuilder, item); + g_variant_builder_close(sessionBuilder); + + if (backForwardListState.currentIndex) + g_variant_builder_add(sessionBuilder, "mu", TRUE, backForwardListState.currentIndex.value()); + else + g_variant_builder_add(sessionBuilder, "mu", FALSE); +} + +static GBytes* encodeSessionState(const SessionState& sessionState) +{ + GVariantBuilder sessionBuilder; + g_variant_builder_init(&sessionBuilder, G_VARIANT_TYPE(SESSION_STATE_TYPE_STRING_V1)); + g_variant_builder_add(&sessionBuilder, "q", g_sessionStateVersion); + encodeBackForwardListState(&sessionBuilder, sessionState.backForwardListState); + GRefPtr<GVariant> variant = g_variant_builder_end(&sessionBuilder); + return g_variant_get_data_as_bytes(variant.get()); +} + +static inline bool decodeHTTPBody(GVariant* httpBodyVariant, HTTPBody& httpBody) +{ + gboolean hasHTTPBody; + const char* contentType; + GUniqueOutPtr<GVariantIter> elementsIter; + g_variant_get(httpBodyVariant, HTTP_BODY_FORMAT_STRING_V1, &hasHTTPBody, &contentType, &elementsIter.outPtr()); + if (!hasHTTPBody) + return false; + httpBody.contentType = String::fromUTF8(contentType); + gsize elementsLength = g_variant_iter_n_children(elementsIter.get()); + if (!elementsLength) + return true; + httpBody.elements.reserveInitialCapacity(elementsLength); + unsigned type; + GVariantIter* dataIter; + const char* filePath; + gint64 fileStart; + gboolean hasFileLength; + gint64 fileLength; + gboolean hasFileModificationTime; + gdouble fileModificationTime; + const char* blobURLString; + while (g_variant_iter_loop(elementsIter.get(), HTTP_BODY_ELEMENT_FORMAT_STRING_V1, &type, &dataIter, &filePath, &fileStart, &hasFileLength, &fileLength, &hasFileModificationTime, &fileModificationTime, &blobURLString)) { + HTTPBody::Element element; + element.type = toHTTPBodyElementType(type); + if (gsize dataLength = g_variant_iter_n_children(dataIter)) { + element.data.reserveInitialCapacity(dataLength); + guchar dataValue; + while (g_variant_iter_next(dataIter, "y", &dataValue)) + element.data.uncheckedAppend(dataValue); + } + element.filePath = String::fromUTF8(filePath); + element.fileStart = fileStart; + if (hasFileLength) + element.fileLength = fileLength; + if (hasFileModificationTime) + element.expectedFileModificationTime = fileModificationTime; + element.blobURLString = String::fromUTF8(blobURLString); + + httpBody.elements.uncheckedAppend(WTFMove(element)); + } + + return true; +} + +static inline void decodeFrameState(GVariant* frameStateVariant, FrameState& frameState) +{ + const char* urlString; + const char* originalURLString; + const char* referrer; + const char* target; + GUniqueOutPtr<GVariantIter> documentStateIter; + GUniqueOutPtr<GVariantIter> stateObjectDataIter; + gint64 documentSequenceNumber; + gint64 itemSequenceNumber; + gint32 scrollPositionX, scrollPositionY; + gdouble pageScaleFactor; + GVariant* httpBodyVariant; + GUniqueOutPtr<GVariantIter> childrenIter; + g_variant_get(frameStateVariant, FRAME_STATE_FORMAT_STRING_V1, &urlString, &originalURLString, &referrer, &target, + &documentStateIter.outPtr(), &stateObjectDataIter.outPtr(), &documentSequenceNumber, &itemSequenceNumber, + &scrollPositionX, &scrollPositionY, &pageScaleFactor, &httpBodyVariant, &childrenIter.outPtr()); + frameState.urlString = String::fromUTF8(urlString); + frameState.originalURLString = String::fromUTF8(originalURLString); + // frameState.referrer must not be an empty string since we never want to + // send an empty Referer header. Bug #159606. + if (strlen(referrer)) + frameState.referrer = String::fromUTF8(referrer); + frameState.target = String::fromUTF8(target); + if (gsize documentStateLength = g_variant_iter_n_children(documentStateIter.get())) { + frameState.documentState.reserveInitialCapacity(documentStateLength); + const char* documentStateString; + while (g_variant_iter_next(documentStateIter.get(), "&s", &documentStateString)) + frameState.documentState.uncheckedAppend(String::fromUTF8(documentStateString)); + } + if (stateObjectDataIter) { + Vector<uint8_t> stateObjectVector; + if (gsize stateObjectDataLength = g_variant_iter_n_children(stateObjectDataIter.get())) { + stateObjectVector.reserveInitialCapacity(stateObjectDataLength); + guchar stateObjectDataValue; + while (g_variant_iter_next(stateObjectDataIter.get(), "y", &stateObjectDataValue)) + stateObjectVector.uncheckedAppend(stateObjectDataValue); + } + frameState.stateObjectData = WTFMove(stateObjectVector); + } + frameState.documentSequenceNumber = documentSequenceNumber; + frameState.itemSequenceNumber = itemSequenceNumber; + frameState.scrollPosition.setX(scrollPositionX); + frameState.scrollPosition.setY(scrollPositionY); + frameState.pageScaleFactor = pageScaleFactor; + HTTPBody httpBody; + if (decodeHTTPBody(httpBodyVariant, httpBody)) + frameState.httpBody = WTFMove(httpBody); + g_variant_unref(httpBodyVariant); + while (GRefPtr<GVariant> child = adoptGRef(g_variant_iter_next_value(childrenIter.get()))) { + FrameState childFrameState; + GRefPtr<GVariant> childVariant = adoptGRef(g_variant_get_variant(child.get())); + decodeFrameState(childVariant.get(), childFrameState); + frameState.children.append(WTFMove(childFrameState)); + } +} + +static inline void decodeBackForwardListItemState(GVariantIter* backForwardListStateIter, BackForwardListState& backForwardListState) +{ + gsize backForwardListStateLength = g_variant_iter_n_children(backForwardListStateIter); + if (!backForwardListStateLength) + return; + + backForwardListState.items.reserveInitialCapacity(backForwardListStateLength); + guint64 identifier; + const char* title; + GVariant* frameStateVariant; + unsigned shouldOpenExternalURLsPolicy; + while (g_variant_iter_loop(backForwardListStateIter, BACK_FORWARD_LIST_ITEM_FORMAT_STRING_V1, &identifier, &title, &frameStateVariant, &shouldOpenExternalURLsPolicy)) { + BackForwardListItemState state; + state.identifier = identifier; + state.pageState.title = String::fromUTF8(title); + decodeFrameState(frameStateVariant, state.pageState.mainFrameState); + state.pageState.shouldOpenExternalURLsPolicy = toWebCoreExternalURLsPolicy(shouldOpenExternalURLsPolicy); + backForwardListState.items.uncheckedAppend(WTFMove(state)); + } +} + +static bool decodeSessionState(GBytes* data, SessionState& sessionState) +{ + GRefPtr<GVariant> variant = g_variant_new_from_bytes(G_VARIANT_TYPE(SESSION_STATE_TYPE_STRING_V1), data, FALSE); + if (!g_variant_is_normal_form(variant.get())) + return false; + + guint16 version; + GUniqueOutPtr<GVariantIter> backForwardListStateIter; + gboolean hasCurrentIndex; + guint32 currentIndex; + g_variant_get(variant.get(), SESSION_STATE_TYPE_STRING_V1, &version, &backForwardListStateIter.outPtr(), &hasCurrentIndex, ¤tIndex); + if (!version || version > g_sessionStateVersion) + return false; + + decodeBackForwardListItemState(backForwardListStateIter.get(), sessionState.backForwardListState); + + if (hasCurrentIndex) + sessionState.backForwardListState.currentIndex = currentIndex; + return true; +} + +WebKitWebViewSessionState* webkitWebViewSessionStateCreate(SessionState&& sessionState) +{ + WebKitWebViewSessionState* state = static_cast<WebKitWebViewSessionState*>(fastMalloc(sizeof(WebKitWebViewSessionState))); + new (state) WebKitWebViewSessionState(WTFMove(sessionState)); + return state; +} + +const SessionState& webkitWebViewSessionStateGetSessionState(WebKitWebViewSessionState* state) +{ + return state->sessionState; +} + +/** + * webkit_web_view_session_state_new: + * @data: a #GBytes + * + * Creates a new #WebKitWebViewSessionState from serialized data. + * + * Returns: (transfer full): a new #WebKitWebViewSessionState, or %NULL if @data doesn't contain a + * valid serialized #WebKitWebViewSessionState. + * + * Since: 2.12 + */ +WebKitWebViewSessionState* webkit_web_view_session_state_new(GBytes* data) +{ + g_return_val_if_fail(data, nullptr); + + SessionState sessionState; + if (!decodeSessionState(data, sessionState)) + return nullptr; + return webkitWebViewSessionStateCreate(WTFMove(sessionState)); +} + +/** + * webkit_web_view_session_state_ref: + * @state: a #WebKitWebViewSessionState + * + * Atomically increments the reference count of @state by one. This + * function is MT-safe and may be called from any thread. + * + * Returns: The passed in #WebKitWebViewSessionState + * + * Since: 2.12 + */ +WebKitWebViewSessionState* webkit_web_view_session_state_ref(WebKitWebViewSessionState* state) +{ + g_return_val_if_fail(state, nullptr); + g_atomic_int_inc(&state->referenceCount); + return state; +} + +/** + * webkit_web_view_session_state_unref: + * @state: a #WebKitWebViewSessionState + * + * Atomically decrements the reference count of @state by one. If the + * reference count drops to 0, all memory allocated by the #WebKitWebViewSessionState is + * released. This function is MT-safe and may be called from any thread. + * + * Since: 2.12 + */ +void webkit_web_view_session_state_unref(WebKitWebViewSessionState* state) +{ + g_return_if_fail(state); + if (g_atomic_int_dec_and_test(&state->referenceCount)) { + state->~WebKitWebViewSessionState(); + fastFree(state); + } +} + +/** + * webkit_web_view_session_state_serialize: + * @state: a #WebKitWebViewSessionState + * + * Serializes a #WebKitWebViewSessionState. + * + * Returns: (transfer full): a #GBytes containing the @state serialized. + * + * Since: 2.12 + */ +GBytes* webkit_web_view_session_state_serialize(WebKitWebViewSessionState* state) +{ + g_return_val_if_fail(state, nullptr); + + return encodeSessionState(state->sessionState); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCertificateInfo.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionState.h index eef16405e..73f4a4a69 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitCertificateInfo.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionState.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Samsung Electronics Inc. All rights reserved. + * Copyright (C) 2016 Igalia S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,33 +21,32 @@ #error "Only <webkit2/webkit2.h> can be included directly." #endif -#ifndef WebKitCertificateInfo_h -#define WebKitCertificateInfo_h +#ifndef WebKitWebViewSessionState_h +#define WebKitWebViewSessionState_h -#include <gio/gio.h> #include <glib-object.h> #include <webkit2/WebKitDefines.h> G_BEGIN_DECLS -#define WEBKIT_TYPE_CERTIFICATE_INFO (webkit_certificate_info_get_type()) +#define WEBKIT_TYPE_WEB_VIEW_SESSION_STATE (webkit_web_view_session_state_get_type()) -typedef struct _WebKitCertificateInfo WebKitCertificateInfo; +typedef struct _WebKitWebViewSessionState WebKitWebViewSessionState; WEBKIT_API GType -webkit_certificate_info_get_type (void); +webkit_web_view_session_state_get_type (void); -WEBKIT_API WebKitCertificateInfo * -webkit_certificate_info_copy (WebKitCertificateInfo *info); +WEBKIT_API WebKitWebViewSessionState * +webkit_web_view_session_state_new (GBytes *data); -WEBKIT_API void -webkit_certificate_info_free (WebKitCertificateInfo *info); +WEBKIT_API WebKitWebViewSessionState * +webkit_web_view_session_state_ref (WebKitWebViewSessionState *state); -WEBKIT_API GTlsCertificate * -webkit_certificate_info_get_tls_certificate (WebKitCertificateInfo *info); +WEBKIT_API void +webkit_web_view_session_state_unref (WebKitWebViewSessionState *state); -WEBKIT_API GTlsCertificateFlags -webkit_certificate_info_get_tls_errors (WebKitCertificateInfo *info); +WEBKIT_API GBytes * +webkit_web_view_session_state_serialize (WebKitWebViewSessionState *state); G_END_DECLS diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionStatePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionStatePrivate.h new file mode 100644 index 000000000..4c7f4e15a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionStatePrivate.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "SessionState.h" +#include "WebKitWebViewSessionState.h" + +#ifndef WebKitWebViewSessionStatePrivate_h +#define WebKitWebViewSessionStatePrivate_h + +WebKitWebViewSessionState* webkitWebViewSessionStateCreate(WebKit::SessionState&&); +const WebKit::SessionState& webkitWebViewSessionStateGetSessionState(WebKitWebViewSessionState*); + +#endif // WebKitWebViewSessionStatePrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.cpp new file mode 100644 index 000000000..43d4dee16 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.cpp @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitWebsiteData.h" + +#include "WebKitSecurityOriginPrivate.h" +#include "WebKitWebsiteDataPrivate.h" +#include <glib/gi18n.h> +#include <wtf/HashTable.h> +#include <wtf/Vector.h> + +using namespace WebKit; + +/** + * SECTION: WebKitWebsiteData + * @Short_description: Website data + * @Title: WebKitWebsiteData + * @See_also: #WebKitWebsiteDataManager + * + * WebKitWebsiteData represents data stored in the client by a particular website. + * A website is normally a set of URLs grouped by domain name. You can get the website name, + * which is usually the domain, with webkit_website_data_get_name(). + * Documents loaded from the file system, like file:// URIs, are all grouped in the same WebKitWebsiteData + * with the name "Local files". + * + * A website can store different types of data in the client side. #WebKitWebsiteDataTypes is an enum containing + * all the possible data types; use webkit_website_data_get_types() to get the bitmask of data types. + * It's also possible to know the size of the data stored for some of the #WebKitWebsiteDataTypes by using + * webkit_website_data_get_size(). + * + * A list of WebKitWebsiteData can be retrieved with webkit_website_data_manager_fetch(). See #WebKitWebsiteDataManager + * for more information. + * + * Since: 2.16 + */ +struct _WebKitWebsiteData { + explicit _WebKitWebsiteData(WebsiteDataRecord&& websiteDataDecord) + : record(WTFMove(websiteDataDecord)) + { + } + + WebsiteDataRecord record; + CString displayName; + int referenceCount { 1 }; +}; + +G_DEFINE_BOXED_TYPE(WebKitWebsiteData, webkit_website_data, webkit_website_data_ref, webkit_website_data_unref) + +static bool recordContainsSupportedDataTypes(const WebsiteDataRecord& record) +{ + static const OptionSet<WebsiteDataType> typesSupported = { + WebsiteDataType::MemoryCache, + WebsiteDataType::DiskCache, + WebsiteDataType::OfflineWebApplicationCache, + WebsiteDataType::SessionStorage, + WebsiteDataType::LocalStorage, + WebsiteDataType::WebSQLDatabases, + WebsiteDataType::IndexedDBDatabases, +#if ENABLE(NETSCAPE_PLUGIN_API) + WebsiteDataType::PlugInData, +#endif + WebsiteDataType::Cookies + }; + return record.types.contains(typesSupported); +} + +static WebKitWebsiteDataTypes toWebKitWebsiteDataTypes(OptionSet<WebsiteDataType> types) +{ + uint32_t returnValue = 0; + if (types.contains(WebsiteDataType::MemoryCache)) + returnValue |= WEBKIT_WEBSITE_DATA_MEMORY_CACHE; + if (types.contains(WebsiteDataType::DiskCache)) + returnValue |= WEBKIT_WEBSITE_DATA_DISK_CACHE; + if (types.contains(WebsiteDataType::OfflineWebApplicationCache)) + returnValue |= WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE; + if (types.contains(WebsiteDataType::SessionStorage)) + returnValue |= WEBKIT_WEBSITE_DATA_SESSION_STORAGE; + if (types.contains(WebsiteDataType::LocalStorage)) + returnValue |= WEBKIT_WEBSITE_DATA_LOCAL_STORAGE; + if (types.contains(WebsiteDataType::WebSQLDatabases)) + returnValue |= WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES; + if (types.contains(WebsiteDataType::IndexedDBDatabases)) + returnValue |= WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES; +#if ENABLE(NETSCAPE_PLUGIN_API) + if (types.contains(WebsiteDataType::PlugInData)) + returnValue |= WEBKIT_WEBSITE_DATA_PLUGIN_DATA; +#endif + if (types.contains(WebsiteDataType::Cookies)) + returnValue |= WEBKIT_WEBSITE_DATA_COOKIES; + return static_cast<WebKitWebsiteDataTypes>(returnValue); +} + +WebKitWebsiteData* webkitWebsiteDataCreate(WebsiteDataRecord&& record) +{ + if (!recordContainsSupportedDataTypes(record)) + return nullptr; + + WebKitWebsiteData* websiteData = static_cast<WebKitWebsiteData*>(fastMalloc(sizeof(WebKitWebsiteData))); + new (websiteData) WebKitWebsiteData(WTFMove(record)); + return websiteData; +} + +const WebKit::WebsiteDataRecord& webkitWebsiteDataGetRecord(WebKitWebsiteData* websiteData) +{ + ASSERT(websiteData); + return websiteData->record; +} + +/** + * webkit_website_data_ref: + * @website_data: a #WebKitWebsiteData + * + * Atomically increments the reference count of @website_data by one. + * This function is MT-safe and may be called from any thread. + * + * Returns: The passed #WebKitWebsiteData + * + * Since: 2.16 + */ +WebKitWebsiteData* webkit_website_data_ref(WebKitWebsiteData* websiteData) +{ + g_return_val_if_fail(websiteData, nullptr); + + g_atomic_int_inc(&websiteData->referenceCount); + return websiteData; +} + +/** + * webkit_website_data_unref: + * @website_data: A #WebKitWebsiteData + * + * Atomically decrements the reference count of @website_data by one. + * If the reference count drops to 0, all memory allocated by + * #WebKitWebsiteData is released. This function is MT-safe and may be + * called from any thread. + * + * Since: 2.16 + */ +void webkit_website_data_unref(WebKitWebsiteData* websiteData) +{ + g_return_if_fail(websiteData); + + if (g_atomic_int_dec_and_test(&websiteData->referenceCount)) { + websiteData->~WebKitWebsiteData(); + fastFree(websiteData); + } +} + +/** + * webkit_website_data_get_name: + * @website_data: a #WebKitWebsiteData + * + * Gets the name of #WebKitWebsiteData. This is the website name, normally represented by + * a domain or host name. All local documents are grouped in the same #WebKitWebsiteData using + * the name "Local files". + * + * Returns: the website name of @website_data. + * + * Since: 2.16 + */ +const char* webkit_website_data_get_name(WebKitWebsiteData* websiteData) +{ + g_return_val_if_fail(websiteData, nullptr); + + if (websiteData->displayName.isNull()) { + if (websiteData->record.displayName == "Local documents on your computer") + websiteData->displayName = _("Local files"); + else + websiteData->displayName = websiteData->record.displayName.utf8(); + } + return websiteData->displayName.data(); +} + +/** + * webkit_website_data_get_types: + * @website_data: a #WebKitWebsiteData + * + * Gets the types of data stored in the client for a #WebKitWebsiteData. These are the + * types actually present, not the types queried with webkit_website_data_manager_fetch(). + * + * Returns: a bitmask of #WebKitWebsiteDataTypes in @website_data + * + * Since: 2.16 + */ +WebKitWebsiteDataTypes webkit_website_data_get_types(WebKitWebsiteData* websiteData) +{ + g_return_val_if_fail(websiteData, static_cast<WebKitWebsiteDataTypes>(0)); + + return toWebKitWebsiteDataTypes(websiteData->record.types); +} + +/** + * webkit_website_data_get_size: + * @website_data: a #WebKitWebsiteData + * @types: a bitmask of #WebKitWebsiteDataTypes + * + * Gets the size of the data of types @types in a #WebKitWebsiteData. + * Note that currently the data size is only known for %WEBKIT_WEBSITE_DATA_DISK_CACHE data type + * so for all other types 0 will be returned. + * + * Returns: the size of @website_data for the given @types. + * + * Since: 2.16 + */ +guint64 webkit_website_data_get_size(WebKitWebsiteData* websiteData, WebKitWebsiteDataTypes types) +{ + g_return_val_if_fail(websiteData, 0); + + if (!types || !websiteData->record.size) + return 0; + + guint64 totalSize = 0; + for (auto type : websiteData->record.size->typeSizes.keys()) { + if (type & types) + totalSize += websiteData->record.size->typeSizes.get(type); + } + + return totalSize; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.h new file mode 100644 index 000000000..065047fe1 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitWebsiteData_h +#define WebKitWebsiteData_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_WEBSITE_DATA (webkit_website_data_get_type()) + +typedef struct _WebKitWebsiteData WebKitWebsiteData; + +/** + * WebKitWebsiteDataTypes: + * @WEBKIT_WEBSITE_DATA_MEMORY_CACHE: Memory cache. + * @WEBKIT_WEBSITE_DATA_DISK_CACHE: HTTP disk cache. + * @WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE: Offline web application cache. + * @WEBKIT_WEBSITE_DATA_SESSION_STORAGE: Session storage data. + * @WEBKIT_WEBSITE_DATA_LOCAL_STORAGE: Local storage data. + * @WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES: WebSQL databases. + * @WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES: IndexedDB databases. + * @WEBKIT_WEBSITE_DATA_PLUGIN_DATA: Plugins data. + * @WEBKIT_WEBSITE_DATA_COOKIES: Cookies. + * @WEBKIT_WEBSITE_DATA_ALL: All types. + * + * Enum values with flags representing types of Website data. + * + * Since: 2.16 + */ +typedef enum { + WEBKIT_WEBSITE_DATA_MEMORY_CACHE = 1 << 0, + WEBKIT_WEBSITE_DATA_DISK_CACHE = 1 << 1, + WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE = 1 << 2, + WEBKIT_WEBSITE_DATA_SESSION_STORAGE = 1 << 3, + WEBKIT_WEBSITE_DATA_LOCAL_STORAGE = 1 << 4, + WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES = 1 << 5, + WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES = 1 << 6, + WEBKIT_WEBSITE_DATA_PLUGIN_DATA = 1 << 7, + WEBKIT_WEBSITE_DATA_COOKIES = 1 << 8, + WEBKIT_WEBSITE_DATA_ALL = (1 << 9) - 1 +} WebKitWebsiteDataTypes; + +WEBKIT_API GType +webkit_website_data_get_type (void); + +WEBKIT_API WebKitWebsiteData * +webkit_website_data_ref (WebKitWebsiteData *website_data); + +WEBKIT_API void +webkit_website_data_unref (WebKitWebsiteData *website_data); + +WEBKIT_API const char * +webkit_website_data_get_name (WebKitWebsiteData *website_data); + +WEBKIT_API WebKitWebsiteDataTypes +webkit_website_data_get_types (WebKitWebsiteData *website_data); + +WEBKIT_API guint64 +webkit_website_data_get_size (WebKitWebsiteData *website_data, + WebKitWebsiteDataTypes types); + +G_END_DECLS + +#endif /* WebKitWebsiteData_h */ diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.cpp new file mode 100644 index 000000000..ea430653f --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.cpp @@ -0,0 +1,818 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitWebsiteDataManager.h" + +#include "APIWebsiteDataStore.h" +#include "WebKitCookieManagerPrivate.h" +#include "WebKitWebsiteDataManagerPrivate.h" +#include "WebKitWebsiteDataPrivate.h" +#include "WebsiteDataFetchOption.h" +#include <WebCore/FileSystem.h> +#include <glib/gi18n-lib.h> +#include <wtf/glib/GUniquePtr.h> + +using namespace WebKit; + +/** + * SECTION: WebKitWebsiteDataManager + * @Short_description: Website data manager + * @Title: WebKitWebsiteDataManager + * @See_also: #WebKitWebContext, #WebKitWebsiteData + * + * WebKitWebsiteDataManager allows you to manage the data that websites + * can store in the client file system like databases or caches. + * You can use WebKitWebsiteDataManager to configure the local directories + * where the Website data will be stored, by creating a new manager with + * webkit_website_data_manager_new() passing the values you want to set. + * You can set all the possible configuration values or only some of them, + * a default value will be used automatically for the configuration options + * not provided. #WebKitWebsiteDataManager:base-data-directory and + * #WebKitWebsiteDataManager:base-cache-directory are two special properties + * that can be used to set a common base directory for all Website data and + * caches. It's possible to provide both, a base directory and a specific value, + * but in that case, the specific value takes precedence over the base directory. + * The newly created WebKitWebsiteDataManager must be passed as a construct property + * to a #WebKitWebContext, you can use webkit_web_context_new_with_website_data_manager() + * to create a new #WebKitWebContext with a WebKitWebsiteDataManager. + * In case you don't want to set any specific configuration, you don't need to create + * a WebKitWebsiteDataManager, the #WebKitWebContext will create a WebKitWebsiteDataManager + * with the default configuration. To get the WebKitWebsiteDataManager of a #WebKitWebContext + * you can use webkit_web_context_get_website_data_manager(). + * + * A WebKitWebsiteDataManager can also be ephemeral and then all the directories configuration + * is not needed because website data will never persist. You can create an ephemeral WebKitWebsiteDataManager + * with webkit_website_data_manager_new_ephemeral(). Then you can pass an ephemeral WebKitWebsiteDataManager to + * a #WebKitWebContext to make it ephemeral or use webkit_web_context_new_ephemeral() and the WebKitWebsiteDataManager + * will be automatically created by the #WebKitWebContext. + * + * WebKitWebsiteDataManager can also be used to fetch websites data, remove data + * stored by particular websites, or clear data for all websites modified since a given + * period of time. + * + * Since: 2.10 + */ + +using namespace WebKit; + +enum { + PROP_0, + + PROP_BASE_DATA_DIRECTORY, + PROP_BASE_CACHE_DIRECTORY, + PROP_LOCAL_STORAGE_DIRECTORY, + PROP_DISK_CACHE_DIRECTORY, + PROP_APPLICATION_CACHE_DIRECTORY, + PROP_INDEXEDDB_DIRECTORY, + PROP_WEBSQL_DIRECTORY, + PROP_IS_EPHEMERAL +}; + +struct _WebKitWebsiteDataManagerPrivate { + ~_WebKitWebsiteDataManagerPrivate() + { + ASSERT(processPools.isEmpty()); + } + + RefPtr<API::WebsiteDataStore> websiteDataStore; + GUniquePtr<char> baseDataDirectory; + GUniquePtr<char> baseCacheDirectory; + GUniquePtr<char> localStorageDirectory; + GUniquePtr<char> diskCacheDirectory; + GUniquePtr<char> applicationCacheDirectory; + GUniquePtr<char> indexedDBDirectory; + GUniquePtr<char> webSQLDirectory; + + GRefPtr<WebKitCookieManager> cookieManager; + Vector<WebProcessPool*> processPools; +}; + +WEBKIT_DEFINE_TYPE(WebKitWebsiteDataManager, webkit_website_data_manager, G_TYPE_OBJECT) + +static void webkitWebsiteDataManagerGetProperty(GObject* object, guint propID, GValue* value, GParamSpec* paramSpec) +{ + WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(object); + + switch (propID) { + case PROP_BASE_DATA_DIRECTORY: + g_value_set_string(value, webkit_website_data_manager_get_base_data_directory(manager)); + break; + case PROP_BASE_CACHE_DIRECTORY: + g_value_set_string(value, webkit_website_data_manager_get_base_cache_directory(manager)); + break; + case PROP_LOCAL_STORAGE_DIRECTORY: + g_value_set_string(value, webkit_website_data_manager_get_local_storage_directory(manager)); + break; + case PROP_DISK_CACHE_DIRECTORY: + g_value_set_string(value, webkit_website_data_manager_get_disk_cache_directory(manager)); + break; + case PROP_APPLICATION_CACHE_DIRECTORY: + g_value_set_string(value, webkit_website_data_manager_get_offline_application_cache_directory(manager)); + break; + case PROP_INDEXEDDB_DIRECTORY: + g_value_set_string(value, webkit_website_data_manager_get_indexeddb_directory(manager)); + break; + case PROP_WEBSQL_DIRECTORY: + g_value_set_string(value, webkit_website_data_manager_get_websql_directory(manager)); + break; + case PROP_IS_EPHEMERAL: + g_value_set_boolean(value, webkit_website_data_manager_is_ephemeral(manager)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec); + } +} + +static void webkitWebsiteDataManagerSetProperty(GObject* object, guint propID, const GValue* value, GParamSpec* paramSpec) +{ + WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(object); + + switch (propID) { + case PROP_BASE_DATA_DIRECTORY: + manager->priv->baseDataDirectory.reset(g_value_dup_string(value)); + break; + case PROP_BASE_CACHE_DIRECTORY: + manager->priv->baseCacheDirectory.reset(g_value_dup_string(value)); + break; + case PROP_LOCAL_STORAGE_DIRECTORY: + manager->priv->localStorageDirectory.reset(g_value_dup_string(value)); + break; + case PROP_DISK_CACHE_DIRECTORY: + manager->priv->diskCacheDirectory.reset(g_value_dup_string(value)); + break; + case PROP_APPLICATION_CACHE_DIRECTORY: + manager->priv->applicationCacheDirectory.reset(g_value_dup_string(value)); + break; + case PROP_INDEXEDDB_DIRECTORY: + manager->priv->indexedDBDirectory.reset(g_value_dup_string(value)); + break; + case PROP_WEBSQL_DIRECTORY: + manager->priv->webSQLDirectory.reset(g_value_dup_string(value)); + break; + case PROP_IS_EPHEMERAL: + if (g_value_get_boolean(value)) + manager->priv->websiteDataStore = API::WebsiteDataStore::createNonPersistentDataStore(); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec); + } +} + +static void webkitWebsiteDataManagerConstructed(GObject* object) +{ + G_OBJECT_CLASS(webkit_website_data_manager_parent_class)->constructed(object); + + WebKitWebsiteDataManagerPrivate* priv = WEBKIT_WEBSITE_DATA_MANAGER(object)->priv; + if (priv->baseDataDirectory) { + if (!priv->localStorageDirectory) + priv->localStorageDirectory.reset(g_build_filename(priv->baseDataDirectory.get(), "localstorage", nullptr)); + if (!priv->indexedDBDirectory) + priv->indexedDBDirectory.reset(g_build_filename(priv->baseDataDirectory.get(), "databases", "indexeddb", nullptr)); + if (!priv->webSQLDirectory) + priv->webSQLDirectory.reset(g_build_filename(priv->baseDataDirectory.get(), "databases", nullptr)); + } + + if (priv->baseCacheDirectory) { + if (!priv->diskCacheDirectory) + priv->diskCacheDirectory.reset(g_strdup(priv->baseCacheDirectory.get())); + if (!priv->applicationCacheDirectory) + priv->applicationCacheDirectory.reset(g_build_filename(priv->baseCacheDirectory.get(), "applications", nullptr)); + } +} + +static void webkit_website_data_manager_class_init(WebKitWebsiteDataManagerClass* findClass) +{ + GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass); + + gObjectClass->get_property = webkitWebsiteDataManagerGetProperty; + gObjectClass->set_property = webkitWebsiteDataManagerSetProperty; + gObjectClass->constructed = webkitWebsiteDataManagerConstructed; + + /** + * WebKitWebsiteDataManager:base-data-directory: + * + * The base directory for Website data. This is used as a base directory + * for any Website data when no specific data directory has been provided. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_BASE_DATA_DIRECTORY, + g_param_spec_string( + "base-data-directory", + _("Base Data Directory"), + _("The base directory for Website data"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebsiteDataManager:base-cache-directory: + * + * The base directory for Website cache. This is used as a base directory + * for any Website cache when no specific cache directory has been provided. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_BASE_CACHE_DIRECTORY, + g_param_spec_string( + "base-cache-directory", + _("Base Cache Directory"), + _("The base directory for Website cache"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebsiteDataManager:local-storage-directory: + * + * The directory where local storage data will be stored. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_LOCAL_STORAGE_DIRECTORY, + g_param_spec_string( + "local-storage-directory", + _("Local Storage Directory"), + _("The directory where local storage data will be stored"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebsiteDataManager:disk-cache-directory: + * + * The directory where HTTP disk cache will be stored. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_DISK_CACHE_DIRECTORY, + g_param_spec_string( + "disk-cache-directory", + _("Disk Cache Directory"), + _("The directory where HTTP disk cache will be stored"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebsiteDataManager:offline-application-cache-directory: + * + * The directory where offline web application cache will be stored. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_APPLICATION_CACHE_DIRECTORY, + g_param_spec_string( + "offline-application-cache-directory", + _("Offline Web Application Cache Directory"), + _("The directory where offline web application cache will be stored"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebsiteDataManager:indexeddb-directory: + * + * The directory where IndexedDB databases will be stored. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_INDEXEDDB_DIRECTORY, + g_param_spec_string( + "indexeddb-directory", + _("IndexedDB Directory"), + _("The directory where IndexedDB databases will be stored"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebsiteDataManager:websql-directory: + * + * The directory where WebSQL databases will be stored. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_WEBSQL_DIRECTORY, + g_param_spec_string( + "websql-directory", + _("WebSQL Directory"), + _("The directory where WebSQL databases will be stored"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebsiteDataManager:is-ephemeral: + * + * Whether the #WebKitWebsiteDataManager is ephemeral. An ephemeral #WebKitWebsiteDataManager + * handles all websites data as non-persistent, and nothing will be written to the client + * storage. Note that if you create an ephemeral #WebKitWebsiteDataManager all other construction + * parameters to configure data directories will be ignored. + * + * Since: 2.16 + */ + g_object_class_install_property( + gObjectClass, + PROP_IS_EPHEMERAL, + g_param_spec_boolean( + "is-ephemeral", + "Is Ephemeral", + _("Whether the WebKitWebsiteDataManager is ephemeral"), + FALSE, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); +} + +WebKitWebsiteDataManager* webkitWebsiteDataManagerCreate(WebsiteDataStore::Configuration&& configuration) +{ + WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(g_object_new(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, nullptr)); + manager->priv->websiteDataStore = API::WebsiteDataStore::create(WTFMove(configuration)); + + return manager; +} + +API::WebsiteDataStore& webkitWebsiteDataManagerGetDataStore(WebKitWebsiteDataManager* manager) +{ + WebKitWebsiteDataManagerPrivate* priv = manager->priv; + if (!priv->websiteDataStore) { + WebsiteDataStore::Configuration configuration; + configuration.localStorageDirectory = !priv->localStorageDirectory ? + API::WebsiteDataStore::defaultLocalStorageDirectory() : WebCore::stringFromFileSystemRepresentation(priv->localStorageDirectory.get()); + configuration.networkCacheDirectory = !priv->diskCacheDirectory ? + API::WebsiteDataStore::defaultNetworkCacheDirectory() : WebCore::pathByAppendingComponent(WebCore::stringFromFileSystemRepresentation(priv->diskCacheDirectory.get()), networkCacheSubdirectory); + configuration.applicationCacheDirectory = !priv->applicationCacheDirectory ? + API::WebsiteDataStore::defaultApplicationCacheDirectory() : WebCore::stringFromFileSystemRepresentation(priv->applicationCacheDirectory.get()); + configuration.webSQLDatabaseDirectory = !priv->webSQLDirectory ? + API::WebsiteDataStore::defaultWebSQLDatabaseDirectory() : WebCore::stringFromFileSystemRepresentation(priv->webSQLDirectory.get()); + configuration.mediaKeysStorageDirectory = API::WebsiteDataStore::defaultMediaKeysStorageDirectory(); + priv->websiteDataStore = API::WebsiteDataStore::create(WTFMove(configuration)); + } + + return *priv->websiteDataStore; +} + +void webkitWebsiteDataManagerAddProcessPool(WebKitWebsiteDataManager* manager, WebProcessPool& processPool) +{ + ASSERT(!manager->priv->processPools.contains(&processPool)); + manager->priv->processPools.append(&processPool); +} + +void webkitWebsiteDataManagerRemoveProcessPool(WebKitWebsiteDataManager* manager, WebProcessPool& processPool) +{ + ASSERT(manager->priv->processPools.contains(&processPool)); + manager->priv->processPools.removeFirst(&processPool); +} + +const Vector<WebProcessPool*>& webkitWebsiteDataManagerGetProcessPools(WebKitWebsiteDataManager* manager) +{ + return manager->priv->processPools; +} + +/** + * webkit_website_data_manager_new: + * @first_option_name: name of the first option to set + * @...: value of first option, followed by more options, %NULL-terminated + * + * Creates a new #WebKitWebsiteDataManager with the given options. It must + * be passed as construction parameter of a #WebKitWebContext. + * + * Returns: (transfer full): the newly created #WebKitWebsiteDataManager + * + * Since: 2.10 + */ +WebKitWebsiteDataManager* webkit_website_data_manager_new(const gchar* firstOptionName, ...) +{ + va_list args; + va_start(args, firstOptionName); + WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(g_object_new_valist(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, firstOptionName, args)); + va_end(args); + + return manager; +} + +/** + * webkit_website_data_manager_new_ephemeral: + * + * Creates an ephemeral #WebKitWebsiteDataManager. See #WebKitWebsiteDataManager:is-ephemeral for more details. + * + * Returns: (transfer full): a new ephemeral #WebKitWebsiteDataManager. + * + * Since: 2.16 + */ +WebKitWebsiteDataManager* webkit_website_data_manager_new_ephemeral() +{ + return WEBKIT_WEBSITE_DATA_MANAGER(g_object_new(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, "is-ephemeral", TRUE, nullptr)); +} + +/** + * webkit_website_data_manager_is_ephemeral: + * @manager: a #WebKitWebsiteDataManager + * + * Get whether a #WebKitWebsiteDataManager is ephemeral. See #WebKitWebsiteDataManager::is-ephemerla for more details. + * + * Returns: %TRUE if @manager is epheral or %FALSE otherwise. + * + * Since: 2.16 + */ +gboolean webkit_website_data_manager_is_ephemeral(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), FALSE); + + return manager->priv->websiteDataStore && !manager->priv->websiteDataStore->isPersistent(); +} + +/** + * webkit_website_data_manager_get_base_data_directory: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitWebsiteDataManager:base-data-directory property. + * + * Returns: (allow-none): the base directory for Website data, or %NULL if + * #WebKitWebsiteDataManager:base-data-directory was not provided or @manager is ephemeral. + * + * Since: 2.10 + */ +const gchar* webkit_website_data_manager_get_base_data_directory(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + if (manager->priv->websiteDataStore && !manager->priv->websiteDataStore->isPersistent()) + return nullptr; + + return manager->priv->baseDataDirectory.get(); +} + +/** + * webkit_website_data_manager_get_base_cache_directory: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitWebsiteDataManager:base-cache-directory property. + * + * Returns: (allow-none): the base directory for Website cache, or %NULL if + * #WebKitWebsiteDataManager:base-cache-directory was not provided or @manager is ephemeral. + * + * Since: 2.10 + */ +const gchar* webkit_website_data_manager_get_base_cache_directory(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + if (manager->priv->websiteDataStore && !manager->priv->websiteDataStore->isPersistent()) + return nullptr; + + return manager->priv->baseCacheDirectory.get(); +} + +/** + * webkit_website_data_manager_get_local_storage_directory: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitWebsiteDataManager:local-storage-directory property. + * + * Returns: (allow-none): the directory where local storage data is stored or %NULL if @manager is ephemeral. + * + * Since: 2.10 + */ +const gchar* webkit_website_data_manager_get_local_storage_directory(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + WebKitWebsiteDataManagerPrivate* priv = manager->priv; + if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent()) + return nullptr; + + if (!priv->localStorageDirectory) + priv->localStorageDirectory.reset(g_strdup(API::WebsiteDataStore::defaultLocalStorageDirectory().utf8().data())); + return priv->localStorageDirectory.get(); +} + +/** + * webkit_website_data_manager_get_disk_cache_directory: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitWebsiteDataManager:disk-cache-directory property. + * + * Returns: (allow-none): the directory where HTTP disk cache is stored or %NULL if @manager is ephemeral. + * + * Since: 2.10 + */ +const gchar* webkit_website_data_manager_get_disk_cache_directory(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + WebKitWebsiteDataManagerPrivate* priv = manager->priv; + if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent()) + return nullptr; + + if (!priv->diskCacheDirectory) { + // The default directory already has the subdirectory. + priv->diskCacheDirectory.reset(g_strdup(WebCore::directoryName(API::WebsiteDataStore::defaultNetworkCacheDirectory()).utf8().data())); + } + return priv->diskCacheDirectory.get(); +} + +/** + * webkit_website_data_manager_get_offline_application_cache_directory: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitWebsiteDataManager:offline-application-cache-directory property. + * + * Returns: (allow-none): the directory where offline web application cache is stored or %NULL if @manager is ephemeral. + * + * Since: 2.10 + */ +const gchar* webkit_website_data_manager_get_offline_application_cache_directory(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + WebKitWebsiteDataManagerPrivate* priv = manager->priv; + if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent()) + return nullptr; + + if (!priv->applicationCacheDirectory) + priv->applicationCacheDirectory.reset(g_strdup(API::WebsiteDataStore::defaultApplicationCacheDirectory().utf8().data())); + return priv->applicationCacheDirectory.get(); +} + +/** + * webkit_website_data_manager_get_indexeddb_directory: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitWebsiteDataManager:indexeddb-directory property. + * + * Returns: (allow-none): the directory where IndexedDB databases are stored or %NULL if @manager is ephemeral. + * + * Since: 2.10 + */ +const gchar* webkit_website_data_manager_get_indexeddb_directory(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + WebKitWebsiteDataManagerPrivate* priv = manager->priv; + if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent()) + return nullptr; + + if (!priv->indexedDBDirectory) + priv->indexedDBDirectory.reset(g_strdup(API::WebsiteDataStore::defaultIndexedDBDatabaseDirectory().utf8().data())); + return priv->indexedDBDirectory.get(); +} + +/** + * webkit_website_data_manager_get_websql_directory: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitWebsiteDataManager:websql-directory property. + * + * Returns: (allow-none): the directory where WebSQL databases are stored or %NULL if @manager is ephemeral. + * + * Since: 2.10 + */ +const gchar* webkit_website_data_manager_get_websql_directory(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + WebKitWebsiteDataManagerPrivate* priv = manager->priv; + if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent()) + return nullptr; + + if (!priv->webSQLDirectory) + priv->webSQLDirectory.reset(g_strdup(API::WebsiteDataStore::defaultWebSQLDatabaseDirectory().utf8().data())); + return priv->webSQLDirectory.get(); +} + +/** + * webkit_website_data_manager_get_cookie_manager: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitCookieManager of @manager. + * + * Returns: (transfer none): a #WebKitCookieManager + * + * Since: 2.16 + */ +WebKitCookieManager* webkit_website_data_manager_get_cookie_manager(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + if (!manager->priv->cookieManager) + manager->priv->cookieManager = adoptGRef(webkitCookieManagerCreate(manager)); + + return manager->priv->cookieManager.get(); +} + +static OptionSet<WebsiteDataType> toWebsiteDataTypes(WebKitWebsiteDataTypes types) +{ + OptionSet<WebsiteDataType> returnValue; + if (types & WEBKIT_WEBSITE_DATA_MEMORY_CACHE) + returnValue |= WebsiteDataType::MemoryCache; + if (types & WEBKIT_WEBSITE_DATA_DISK_CACHE) + returnValue |= WebsiteDataType::DiskCache; + if (types & WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE) + returnValue |= WebsiteDataType::OfflineWebApplicationCache; + if (types & WEBKIT_WEBSITE_DATA_SESSION_STORAGE) + returnValue |= WebsiteDataType::SessionStorage; + if (types & WEBKIT_WEBSITE_DATA_LOCAL_STORAGE) + returnValue |= WebsiteDataType::LocalStorage; + if (types & WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES) + returnValue |= WebsiteDataType::WebSQLDatabases; + if (types & WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES) + returnValue |= WebsiteDataType::IndexedDBDatabases; +#if ENABLE(NETSCAPE_PLUGIN_API) + if (types & WEBKIT_WEBSITE_DATA_PLUGIN_DATA) + returnValue |= WebsiteDataType::PlugInData; +#endif + if (types & WEBKIT_WEBSITE_DATA_COOKIES) + returnValue |= WebsiteDataType::Cookies; + return returnValue; +} + +/** + * webkit_website_data_manager_fetch: + * @manager: a #WebKitWebsiteDataManager + * @types: #WebKitWebsiteDataTypes + * @cancellable: (allow-none): a #GCancellable or %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously get the list of #WebKitWebsiteData for the given @types. + * + * When the operation is finished, @callback will be called. You can then call + * webkit_website_data_manager_fetch_finish() to get the result of the operation. + * + * Since: 2.16 + */ +void webkit_website_data_manager_fetch(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData) +{ + g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager)); + + GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData)); + manager->priv->websiteDataStore->websiteDataStore().fetchData(toWebsiteDataTypes(types), WebsiteDataFetchOption::ComputeSizes, [task = WTFMove(task)] (Vector<WebsiteDataRecord> records) { + GList* dataList = nullptr; + while (!records.isEmpty()) { + if (auto* data = webkitWebsiteDataCreate(records.takeLast())) + dataList = g_list_prepend(dataList, data); + } + + g_task_return_pointer(task.get(), dataList, [](gpointer data) { + g_list_free_full(static_cast<GList*>(data), reinterpret_cast<GDestroyNotify>(webkit_website_data_unref)); + }); + }); +} + +/** + * webkit_website_data_manager_fetch_finish: + * @manager: a #WebKitWebsiteDataManager + * @result: a #GAsyncResult + * @error: return location for error or %NULL to ignore + * + * Finish an asynchronous operation started with webkit_website_data_manager_fetch(). + * + * Returns: (element-type WebKitWebsiteData) (transfer full): a #GList of #WebKitWebsiteData. You must free the #GList with + * g_list_free() and unref the #WebKitWebsiteData<!-- -->s with webkit_website_data_unref() when you're done with them. + * + * Since: 2.16 + */ +GList* webkit_website_data_manager_fetch_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + g_return_val_if_fail(g_task_is_valid(result, manager), nullptr); + + return static_cast<GList*>(g_task_propagate_pointer(G_TASK(result), error)); +} + +/** + * webkit_website_data_manager_remove: + * @manager: a #WebKitWebsiteDataManager + * @types: #WebKitWebsiteDataTypes + * @website_data: (element-type WebKitWebsiteData): a #GList of #WebKitWebsiteData + * @cancellable: (allow-none): a #GCancellable or %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously removes the website data of the for the given @types for websites in the given @website_data list. + * Use webkit_website_data_manager_clear() if you want to remove the website data for all sites. + * + * When the operation is finished, @callback will be called. You can then call + * webkit_website_data_manager_remove_finish() to get the result of the operation. + * + * Since: 2.16 + */ +void webkit_website_data_manager_remove(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GList* websiteData, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData) +{ + g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager)); + g_return_if_fail(websiteData); + + Vector<WebsiteDataRecord> records; + for (GList* item = websiteData; item; item = g_list_next(item)) { + WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(item->data); + + if (webkit_website_data_get_types(data) & types) + records.append(webkitWebsiteDataGetRecord(data)); + } + + GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData)); + if (records.isEmpty()) { + g_task_return_boolean(task.get(), TRUE); + return; + } + + manager->priv->websiteDataStore->websiteDataStore().removeData(toWebsiteDataTypes(types), records, [task = WTFMove(task)] { + g_task_return_boolean(task.get(), TRUE); + }); +} + +/** + * webkit_website_data_manager_remove_finish: + * @manager: a #WebKitWebsiteDataManager + * @result: a #GAsyncResult + * @error: return location for error or %NULL to ignore + * + * Finish an asynchronous operation started with webkit_website_data_manager_remove(). + * + * Returns: %TRUE if website data resources were succesfully removed, or %FALSE otherwise. + * + * Since: 2.16 + */ +gboolean webkit_website_data_manager_remove_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), FALSE); + g_return_val_if_fail(g_task_is_valid(result, manager), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/** + * webkit_website_data_manager_clear: + * @manager: a #WebKitWebsiteDataManager + * @types: #WebKitWebsiteDataTypes + * @timespan: a #GTimeSpan + * @cancellable: (allow-none): a #GCancellable or %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously clear the website data of the given @types modified in the past @timespan. + * If @timespan is 0, all website data will be removed. + * + * When the operation is finished, @callback will be called. You can then call + * webkit_website_data_manager_clear_finish() to get the result of the operation. + * + * Due to implementation limitations, this function does not currently delete + * any stored cookies if @timespan is nonzero. This behavior may change in the + * future. + * + * Since: 2.16 + */ +void webkit_website_data_manager_clear(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GTimeSpan timeSpan, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData) +{ + g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager)); + + std::chrono::system_clock::time_point timePoint = timeSpan ? std::chrono::system_clock::now() - std::chrono::microseconds(timeSpan) : std::chrono::system_clock::from_time_t(0); + GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData)); + manager->priv->websiteDataStore->websiteDataStore().removeData(toWebsiteDataTypes(types), timePoint, [task = WTFMove(task)] { + g_task_return_boolean(task.get(), TRUE); + }); +} + +/** + * webkit_website_data_manager_clear_finish: + * @manager: a #WebKitWebsiteDataManager + * @result: a #GAsyncResult + * @error: return location for error or %NULL to ignore + * + * Finish an asynchronous operation started with webkit_website_data_manager_clear() + * + * Returns: %TRUE if website data was succesfully cleared, or %FALSE otherwise. + * + * Since: 2.16 + */ +gboolean webkit_website_data_manager_clear_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), FALSE); + g_return_val_if_fail(g_task_is_valid(result, manager), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.h new file mode 100644 index 000000000..cc62ad3d4 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitWebsiteDataManager_h +#define WebKitWebsiteDataManager_h + +#include <gio/gio.h> +#include <webkit2/WebKitCookieManager.h> +#include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitWebsiteData.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_WEBSITE_DATA_MANAGER (webkit_website_data_manager_get_type()) +#define WEBKIT_WEBSITE_DATA_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_WEBSITE_DATA_MANAGER, WebKitWebsiteDataManager)) +#define WEBKIT_IS_WEBSITE_DATA_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_WEBSITE_DATA_MANAGER)) +#define WEBKIT_WEBSITE_DATA_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_WEBSITE_DATA_MANAGER, WebKitWebsiteDataManagerClass)) +#define WEBKIT_IS_WEBSITE_DATA_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_WEBSITE_DATA_MANAGER)) +#define WEBKIT_WEBSITE_DATA_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_WEBSITE_DATA_MANAGER, WebKitWebsiteDataManagerClass)) + +typedef struct _WebKitWebsiteDataManager WebKitWebsiteDataManager; +typedef struct _WebKitWebsiteDataManagerClass WebKitWebsiteDataManagerClass; +typedef struct _WebKitWebsiteDataManagerPrivate WebKitWebsiteDataManagerPrivate; + +struct _WebKitWebsiteDataManager { + GObject parent; + + WebKitWebsiteDataManagerPrivate *priv; +}; + +struct _WebKitWebsiteDataManagerClass { + GObjectClass parent_class; + + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); +}; + +WEBKIT_API GType +webkit_website_data_manager_get_type (void); + +WEBKIT_API WebKitWebsiteDataManager * +webkit_website_data_manager_new (const gchar *first_option_name, + ...); +WEBKIT_API WebKitWebsiteDataManager * +webkit_website_data_manager_new_ephemeral (void); + +WEBKIT_API gboolean +webkit_website_data_manager_is_ephemeral (WebKitWebsiteDataManager* manager); + +WEBKIT_API const gchar * +webkit_website_data_manager_get_base_data_directory (WebKitWebsiteDataManager *manager); + +WEBKIT_API const gchar * +webkit_website_data_manager_get_base_cache_directory (WebKitWebsiteDataManager *manager); + +WEBKIT_API const gchar * +webkit_website_data_manager_get_local_storage_directory (WebKitWebsiteDataManager *manager); + +WEBKIT_API const gchar * +webkit_website_data_manager_get_disk_cache_directory (WebKitWebsiteDataManager *manager); + +WEBKIT_API const gchar * +webkit_website_data_manager_get_offline_application_cache_directory (WebKitWebsiteDataManager *manager); + +WEBKIT_API const gchar * +webkit_website_data_manager_get_indexeddb_directory (WebKitWebsiteDataManager *manager); + +WEBKIT_API const gchar * +webkit_website_data_manager_get_websql_directory (WebKitWebsiteDataManager *manager); + +WEBKIT_API WebKitCookieManager * +webkit_website_data_manager_get_cookie_manager (WebKitWebsiteDataManager *manager); + +WEBKIT_API void +webkit_website_data_manager_fetch (WebKitWebsiteDataManager *manager, + WebKitWebsiteDataTypes types, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +WEBKIT_API GList * +webkit_website_data_manager_fetch_finish (WebKitWebsiteDataManager *manager, + GAsyncResult *result, + GError **error); +WEBKIT_API void +webkit_website_data_manager_remove (WebKitWebsiteDataManager *manager, + WebKitWebsiteDataTypes types, + GList *website_data, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +WEBKIT_API gboolean +webkit_website_data_manager_remove_finish (WebKitWebsiteDataManager *manager, + GAsyncResult *result, + GError **error); + +WEBKIT_API void +webkit_website_data_manager_clear (WebKitWebsiteDataManager *manager, + WebKitWebsiteDataTypes types, + GTimeSpan timespan, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +WEBKIT_API gboolean +webkit_website_data_manager_clear_finish (WebKitWebsiteDataManager *manager, + GAsyncResult *result, + GError **error); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManagerPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManagerPrivate.h new file mode 100644 index 000000000..46379aaf3 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManagerPrivate.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "APIWebsiteDataStore.h" +#include "WebKitPrivate.h" +#include "WebProcessPool.h" +#include "WebsiteDataStore.h" + +WebKitWebsiteDataManager* webkitWebsiteDataManagerCreate(WebKit::WebsiteDataStore::Configuration&&); +API::WebsiteDataStore& webkitWebsiteDataManagerGetDataStore(WebKitWebsiteDataManager*); +void webkitWebsiteDataManagerAddProcessPool(WebKitWebsiteDataManager*, WebKit::WebProcessPool&); +void webkitWebsiteDataManagerRemoveProcessPool(WebKitWebsiteDataManager*, WebKit::WebProcessPool&); +const Vector<WebKit::WebProcessPool*>& webkitWebsiteDataManagerGetProcessPools(WebKitWebsiteDataManager*); + diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataPrivate.h new file mode 100644 index 000000000..509591fb4 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataPrivate.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "WebKitPrivate.h" +#include "WebKitWebsiteData.h" +#include "WebsiteDataRecord.h" + +WebKitWebsiteData* webkitWebsiteDataCreate(WebKit::WebsiteDataRecord&&); +const WebKit::WebsiteDataRecord& webkitWebsiteDataGetRecord(WebKitWebsiteData*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWindowProperties.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWindowProperties.cpp index a40e6db4d..5e225db78 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWindowProperties.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWindowProperties.cpp @@ -20,12 +20,13 @@ #include "config.h" #include "WebKitWindowProperties.h" +#include "APIDictionary.h" #include "APINumber.h" #include "APIURLRequest.h" -#include "ImmutableDictionary.h" #include "WebKitPrivate.h" #include "WebKitWindowPropertiesPrivate.h" #include <WebCore/IntRect.h> +#include <WebCore/WindowFeatures.h> #include <glib/gi18n-lib.h> using namespace WebKit; @@ -374,54 +375,26 @@ void webkitWindowPropertiesSetFullscreen(WebKitWindowProperties* windowPropertie g_object_notify(G_OBJECT(windowProperties), "fullscreen"); } -void webkitWindowPropertiesUpdateFromWebWindowFeatures(WebKitWindowProperties* windowProperties, ImmutableDictionary* features) +void webkitWindowPropertiesUpdateFromWebWindowFeatures(WebKitWindowProperties* windowProperties, const WindowFeatures& windowFeatures) { GdkRectangle geometry = windowProperties->priv->geometry; - - API::Double* doubleValue = static_cast<API::Double*>(features->get("x")); - if (doubleValue) - geometry.x = doubleValue->value(); - - doubleValue = static_cast<API::Double*>(features->get("y")); - if (doubleValue) - geometry.y = doubleValue->value(); - - doubleValue = static_cast<API::Double*>(features->get("width")); - if (doubleValue) - geometry.width = doubleValue->value(); - - doubleValue = static_cast<API::Double*>(features->get("height")); - if (doubleValue) - geometry.height = doubleValue->value(); + if (windowFeatures.x) + geometry.x = *windowFeatures.x; + if (windowFeatures.y) + geometry.y = *windowFeatures.y; + if (windowFeatures.width) + geometry.width = *windowFeatures.width; + if (windowFeatures.height) + geometry.height = *windowFeatures.height; webkitWindowPropertiesSetGeometry(windowProperties, &geometry); - API::Boolean* booleanValue = static_cast<API::Boolean*>(features->get("menuBarVisible")); - if (booleanValue) - webkitWindowPropertiesSetMenubarVisible(windowProperties, booleanValue->value()); - - booleanValue = static_cast<API::Boolean*>(features->get("statusBarVisible")); - if (booleanValue) - webkitWindowPropertiesSetStatusbarVisible(windowProperties, booleanValue->value()); - - booleanValue = static_cast<API::Boolean*>(features->get("toolBarVisible")); - if (booleanValue) - webkitWindowPropertiesSetToolbarVisible(windowProperties, booleanValue->value()); - - booleanValue = static_cast<API::Boolean*>(features->get("locationBarVisible")); - if (booleanValue) - webkitWindowPropertiesSetLocationbarVisible(windowProperties, booleanValue->value()); - - booleanValue = static_cast<API::Boolean*>(features->get("scrollbarsVisible")); - if (booleanValue) - webkitWindowPropertiesSetScrollbarsVisible(windowProperties, booleanValue->value()); - - booleanValue = static_cast<API::Boolean*>(features->get("resizable")); - if (booleanValue) - webkitWindowPropertiesSetResizable(windowProperties, booleanValue->value()); - - booleanValue = static_cast<API::Boolean*>(features->get("fullscreen")); - if (booleanValue) - webkitWindowPropertiesSetFullscreen(windowProperties, booleanValue->value()); + webkitWindowPropertiesSetMenubarVisible(windowProperties, windowFeatures.menuBarVisible); + webkitWindowPropertiesSetStatusbarVisible(windowProperties, windowFeatures.statusBarVisible); + webkitWindowPropertiesSetToolbarVisible(windowProperties, windowFeatures.toolBarVisible); + webkitWindowPropertiesSetLocationbarVisible(windowProperties, windowFeatures.locationBarVisible); + webkitWindowPropertiesSetScrollbarsVisible(windowProperties, windowFeatures.scrollbarsVisible); + webkitWindowPropertiesSetResizable(windowProperties, windowFeatures.resizable); + webkitWindowPropertiesSetFullscreen(windowProperties, windowFeatures.fullscreen); } /** diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWindowPropertiesPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWindowPropertiesPrivate.h index 8ec17b4ea..05e4b9be0 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWindowPropertiesPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWindowPropertiesPrivate.h @@ -31,7 +31,7 @@ #include "WebKitWindowProperties.h" WebKitWindowProperties* webkitWindowPropertiesCreate(); -void webkitWindowPropertiesUpdateFromWebWindowFeatures(WebKitWindowProperties*, WebKit::ImmutableDictionary* features); +void webkitWindowPropertiesUpdateFromWebWindowFeatures(WebKitWindowProperties*, const WebCore::WindowFeatures&); void webkitWindowPropertiesSetGeometry(WebKitWindowProperties*, GdkRectangle*); void webkitWindowPropertiesSetToolbarVisible(WebKitWindowProperties*, bool toolbarsVisible); void webkitWindowPropertiesSetMenubarVisible(WebKitWindowProperties*, bool menuBarVisible); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebViewBaseInputMethodFilter.cpp b/Source/WebKit2/UIProcess/API/gtk/WebViewBaseInputMethodFilter.cpp deleted file mode 100644 index 8b87c1522..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebViewBaseInputMethodFilter.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "WebViewBaseInputMethodFilter.h" - -#include "NativeWebKeyboardEvent.h" -#include "WebKitWebViewBasePrivate.h" -#include "WebPageProxy.h" -#include <WebCore/Color.h> -#include <WebCore/CompositionResults.h> -#include <WebCore/Editor.h> - -using namespace WebCore; - -namespace WebKit { - -void WebViewBaseInputMethodFilter::setWebView(WebKitWebViewBase* webView) -{ - GtkInputMethodFilter::setWidget(GTK_WIDGET(webView)); - - m_webPageProxy = webkitWebViewBaseGetPage(webView); - ASSERT(m_webPageProxy); -} - -bool WebViewBaseInputMethodFilter::canEdit() -{ - return true; -} - -bool WebViewBaseInputMethodFilter::sendSimpleKeyEvent(GdkEventKey* event, WTF::String simpleString, EventFakedForComposition faked) -{ - ASSERT(m_webPageProxy); - m_webPageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(reinterpret_cast<GdkEvent*>(event), - CompositionResults(simpleString), faked)); - return true; -} - -bool WebViewBaseInputMethodFilter::sendKeyEventWithCompositionResults(GdkEventKey* event, ResultsToSend resultsToSend, EventFakedForComposition faked) -{ - ASSERT(m_webPageProxy); - m_webPageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(reinterpret_cast<GdkEvent*>(event), - CompositionResults(CompositionResults::WillSendCompositionResultsSoon), - faked)); - - if (resultsToSend & Composition && !m_confirmedComposition.isNull()) - confirmCompositionText(m_confirmedComposition); - if (resultsToSend & Preedit && !m_preedit.isNull()) - setPreedit(m_preedit, m_cursorOffset); - return true; -} - -void WebViewBaseInputMethodFilter::confirmCompositionText(String text) -{ - ASSERT(m_webPageProxy); - m_webPageProxy->confirmComposition(text, -1, 0); -} - -void WebViewBaseInputMethodFilter::confirmCurrentComposition() -{ - ASSERT(m_webPageProxy); - m_webPageProxy->confirmComposition(String(), -1, 0); -} - -void WebViewBaseInputMethodFilter::cancelCurrentComposition() -{ - ASSERT(m_webPageProxy); - m_webPageProxy->cancelComposition(); -} - -void WebViewBaseInputMethodFilter::setPreedit(String newPreedit, int cursorOffset) -{ - // TODO: We should parse the PangoAttrList that we get from the IM context here. - Vector<CompositionUnderline> underlines; - underlines.append(CompositionUnderline(0, newPreedit.length(), Color(1, 1, 1), false)); - - ASSERT(m_webPageProxy); - m_webPageProxy->setComposition(newPreedit, underlines, - m_cursorOffset, m_cursorOffset, - 0 /* replacement start */, - 0 /* replacement end */); -} - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/gtk/WebViewBaseInputMethodFilter.h b/Source/WebKit2/UIProcess/API/gtk/WebViewBaseInputMethodFilter.h deleted file mode 100644 index 9cde8b12d..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebViewBaseInputMethodFilter.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef WebViewBaseInputMethodFilter_h -#define WebViewBaseInputMethodFilter_h - -#include "GtkInputMethodFilter.h" -#include "WebPageProxy.h" - -typedef struct _WebKitWebViewBase WebKitWebViewBase; - -namespace WebKit { - -class WebViewBaseInputMethodFilter : public WebCore::GtkInputMethodFilter { -public: - void setWebView(WebKitWebViewBase*); - -protected: - virtual bool sendSimpleKeyEvent(GdkEventKey*, WTF::String eventString, EventFakedForComposition); - virtual bool sendKeyEventWithCompositionResults(GdkEventKey*, ResultsToSend, EventFakedForComposition); - virtual bool canEdit(); - virtual void confirmCompositionText(String); - virtual void confirmCurrentComposition(); - virtual void cancelCurrentComposition(); - virtual void setPreedit(String, int cursorOffset); - -private: - WebPageProxy* m_webPageProxy; -}; - -} // namespace WebKit - -#endif // WebViewBaseInputMethodFilter_h diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt index a098a00d8..995497075 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt @@ -16,7 +16,8 @@ WEBKIT_WEB_VIEW_BASE_GET_CLASS webkit_web_view_base_get_type WebKitWebViewBasePrivate WEBKIT_API -WEBKIT_OBSOLETE_API +WEBKIT_DEPRECATED +WEBKIT_DEPRECATED_FOR </SECTION> <SECTION> @@ -26,10 +27,19 @@ WebKitWebContext WebKitCacheModel WebKitProcessModel WebKitTLSErrorsPolicy +WebKitNetworkProxyMode webkit_web_context_get_default +webkit_web_context_new +webkit_web_context_new_ephemeral +webkit_web_context_new_with_website_data_manager +webkit_web_context_is_ephemeral +webkit_web_context_get_website_data_manager webkit_web_context_get_cache_model webkit_web_context_set_cache_model +webkit_web_context_get_web_process_count_limit +webkit_web_context_set_web_process_count_limit webkit_web_context_clear_cache +webkit_web_context_set_network_proxy_settings webkit_web_context_download_uri webkit_web_context_get_cookie_manager webkit_web_context_get_favicon_database @@ -53,6 +63,7 @@ webkit_web_context_set_disk_cache_directory webkit_web_context_allow_tls_certificate_for_host webkit_web_context_get_process_model webkit_web_context_set_process_model +webkit_web_context_initialize_notification_permissions <SUBSECTION URI Scheme> WebKitURISchemeRequestCallback @@ -73,13 +84,62 @@ webkit_web_context_get_type </SECTION> <SECTION> +<FILE>WebKitUserContent</FILE> +<TITLE>WebKitUserContent</TITLE> +WebKitUserStyleSheet +WebKitUserScript +WebKitUserContentInjectedFrames +WebKitUserStyleLevel +WebKitUserScriptInjectionTime +webkit_user_style_sheet_ref +webkit_user_style_sheet_unref +webkit_user_style_sheet_new +webkit_user_script_ref +webkit_user_script_unref +webkit_user_script_new + +<SUBSECTION Standard> +WEBKIT_TYPE_USER_STYLE_SHEET +WEBKIT_TYPE_USER_SCRIPT + +<SUBSECTION Private> +webkit_user_style_sheet_get_type +webkit_user_script_get_type +</SECTION> + +<SECTION> +<FILE>WebKitUserContentManager</FILE> +<TITLE>WebKitUserContentManager</TITLE> +WebKitUserContentManager +webkit_user_content_manager_new +webkit_user_content_manager_add_style_sheet +webkit_user_content_manager_remove_all_style_sheets +webkit_user_content_manager_add_script +webkit_user_content_manager_remove_all_scripts +webkit_user_content_manager_register_script_message_handler +webkit_user_content_manager_unregister_script_message_handler + +<SUBSECTION Standard> +WEBKIT_IS_USER_CONTENT_MANAGER +WEBKIT_IS_USER_CONTENT_MANAGER_CLASS +WEBKIT_TYPE_USER_CONTENT_MANAGER +WEBKIT_USER_CONTENT_MANAGER +WEBKIT_USER_CONTENT_MANAGER_CLASS +WEBKIT_USER_CONTENT_MANAGER_GET_CLASS +WebKitUserContentManagerClass + +<SUBSECTION Private> +WebKitUserContentManagerPrivate +webkit_user_content_manager_get_type +</SECTION> + +<SECTION> <FILE>WebKitWebView</FILE> <TITLE>WebKitWebView</TITLE> WebKitWebView WebKitLoadEvent WebKitPolicyDecisionType WebKitSaveMode -WebKitViewMode WebKitInsecureContentEvent WebKitSnapshotOptions WebKitSnapshotRegion @@ -91,18 +151,25 @@ WEBKIT_EDITING_COMMAND_PASTE WEBKIT_EDITING_COMMAND_SELECT_ALL WEBKIT_EDITING_COMMAND_UNDO WEBKIT_EDITING_COMMAND_REDO +WEBKIT_EDITING_COMMAND_INSERT_IMAGE +WEBKIT_EDITING_COMMAND_CREATE_LINK <SUBSECTION> webkit_web_view_new webkit_web_view_new_with_context webkit_web_view_new_with_related_view -webkit_web_view_new_with_group +webkit_web_view_new_with_settings +webkit_web_view_new_with_user_content_manager +webkit_web_view_is_ephemeral webkit_web_view_get_context -webkit_web_view_get_group +webkit_web_view_get_user_content_manager +webkit_web_view_get_website_data_manager +webkit_web_view_try_close webkit_web_view_load_uri webkit_web_view_load_html webkit_web_view_load_alternate_html webkit_web_view_load_plain_text +webkit_web_view_load_bytes webkit_web_view_load_request webkit_web_view_can_go_back webkit_web_view_go_back @@ -114,6 +181,7 @@ webkit_web_view_reload webkit_web_view_reload_bypass_cache webkit_web_view_stop_loading webkit_web_view_is_loading +webkit_web_view_is_playing_audio webkit_web_view_get_estimated_load_progress webkit_web_view_get_custom_charset webkit_web_view_set_custom_charset @@ -129,6 +197,7 @@ webkit_web_view_get_zoom_level webkit_web_view_can_execute_editing_command webkit_web_view_can_execute_editing_command_finish webkit_web_view_execute_editing_command +webkit_web_view_execute_editing_command_with_argument webkit_web_view_get_find_controller webkit_web_view_get_inspector webkit_web_view_get_javascript_global_context @@ -142,11 +211,16 @@ webkit_web_view_save_finish webkit_web_view_save_to_file webkit_web_view_save_to_file_finish webkit_web_view_download_uri -webkit_web_view_set_view_mode -webkit_web_view_get_view_mode webkit_web_view_get_tls_info webkit_web_view_get_snapshot webkit_web_view_get_snapshot_finish +webkit_web_view_set_background_color +webkit_web_view_get_background_color +webkit_web_view_set_editable +webkit_web_view_is_editable +webkit_web_view_get_editor_state +webkit_web_view_get_session_state +webkit_web_view_restore_session_state <SUBSECTION WebKitJavascriptResult> WebKitJavascriptResult @@ -165,6 +239,13 @@ webkit_script_dialog_prompt_get_default_text webkit_script_dialog_prompt_set_text webkit_web_view_get_main_resource +<SUBSECTION WebKitWebViewSessionState> +WebKitWebViewSessionState +webkit_web_view_session_state_new +webkit_web_view_session_state_ref +webkit_web_view_session_state_unref +webkit_web_view_session_state_serialize + <SUBSECTION Standard> WebKitWebViewClass WEBKIT_WEB_VIEW @@ -175,11 +256,13 @@ WEBKIT_IS_WEB_VIEW_CLASS WEBKIT_WEB_VIEW_GET_CLASS WEBKIT_TYPE_JAVASCRIPT_RESULT WEBKIT_TYPE_SCRIPT_DIALOG +WEBKIT_TYPE_WEB_VIEW_SESSION_STATE <SUBSECTION Private> webkit_web_view_get_type webkit_javascript_result_get_type webkit_script_dialog_get_type +webkit_web_view_session_state_get_type WebKitWebViewPrivate </SECTION> @@ -276,6 +359,7 @@ webkit_back_forward_list_item_get_type <SECTION> <FILE>WebKitSettings</FILE> WebKitSettings +WebKitHardwareAccelerationPolicy webkit_settings_new webkit_settings_new_with_settings webkit_settings_get_auto_load_images @@ -375,6 +459,12 @@ webkit_settings_get_enable_spatial_navigation webkit_settings_set_enable_spatial_navigation webkit_settings_get_enable_mediasource webkit_settings_set_enable_mediasource +webkit_settings_get_allow_file_access_from_file_urls +webkit_settings_set_allow_file_access_from_file_urls +webkit_settings_get_allow_universal_access_from_file_urls +webkit_settings_set_allow_universal_access_from_file_urls +webkit_settings_get_hardware_acceleration_policy +webkit_settings_set_hardware_acceleration_policy <SUBSECTION Standard> WebKitSettingsClass @@ -396,6 +486,7 @@ WebKitURIRequest webkit_uri_request_new webkit_uri_request_get_uri webkit_uri_request_set_uri +webkit_uri_request_get_http_method webkit_uri_request_get_http_headers <SUBSECTION Standard> @@ -420,6 +511,7 @@ webkit_uri_response_get_status_code webkit_uri_response_get_content_length webkit_uri_response_get_mime_type webkit_uri_response_get_suggested_filename +webkit_uri_response_get_http_headers <SUBSECTION Standard> WebKitURIResponseClass @@ -473,6 +565,8 @@ webkit_download_get_estimated_progress webkit_download_get_elapsed_time webkit_download_get_received_data_length webkit_download_get_web_view +webkit_download_get_allow_overwrite +webkit_download_set_allow_overwrite <SUBSECTION Standard> WebKitDownloadClass @@ -524,6 +618,105 @@ webkit_geolocation_permission_request_get_type </SECTION> <SECTION> +<FILE>WebKitInstallMissingMediaPluginsPermissionRequest</FILE> +WebKitInstallMissingMediaPluginsPermissionRequest +webkit_install_missing_media_plugins_permission_request_get_description + +<SUBSECTION Standard> +WebKitInstallMissingMediaPluginsPermissionRequestClass +WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST +WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST +WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST +WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST_CLASS +WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST_CLASS +WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST_GET_CLASS + +<SUBSECTION Private> +WebKitInstallMissingMediaPluginsPermissionRequestPrivate +webkit_install_missing_media_plugins_permission_request_get_type +</SECTION> + +<SECTION> +<FILE>WebKitNavigationAction</FILE> +WebKitNavigationAction +webkit_navigation_action_copy +webkit_navigation_action_free +webkit_navigation_action_get_navigation_type +webkit_navigation_action_get_mouse_button +webkit_navigation_action_get_modifiers +webkit_navigation_action_get_request +webkit_navigation_action_is_user_gesture + +<SUBSECTION Standard> +WEBKIT_TYPE_NAVIGATION_ACTION + +<SUBSECTION Private> +webkit_navigation_action_get_type +</SECTION> + +<SECTION> +<FILE>WebKitUserMediaPermissionRequest</FILE> +WebKitUserMediaPermissionRequest +webkit_user_media_permission_is_for_audio_device +webkit_user_media_permission_is_for_video_device + +<SUBSECTION Standard> +WebKitUserMediaPermissionRequestClass +WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST +WEBKIT_USER_MEDIA_PERMISSION_REQUEST +WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST +WEBKIT_USER_MEDIA_PERMISSION_REQUEST_CLASS +WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST_CLASS +WEBKIT_USER_MEDIA_PERMISSION_REQUEST_GET_CLASS + +<SUBSECTION Private> +WebKitUserMediaPermissionRequestPrivate +webkit_user_media_permission_request_get_type +</SECTION> + +<SECTION> +<FILE>WebKitNotification</FILE> +WebKitNotification +webkit_notification_get_id +webkit_notification_get_title +webkit_notification_get_body +webkit_notification_get_tag +webkit_notification_close +webkit_notification_clicked + +<SUBSECTION Standard> +WebKitNotificationClass +WEBKIT_TYPE_NOTIFICATION +WEBKIT_IS_NOTIFICATION +WEBKIT_NOTIFICATION +WEBKIT_NOTIFICATION_CLASS +WEBKIT_IS_NOTIFICATION_CLASS +WEBKIT_NOTIFICATION_GET_CLASS + +<SUBSECTION Private> +WebKitNotificationPrivate +webkit_notification_get_type +</SECTION> + +<SECTION> +<FILE>WebKitNotificationPermissionRequest</FILE> +WebKitNotificationPermissionRequest + +<SUBSECTION Standard> +WebKitNotificationPermissionRequestClass +WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST +WEBKIT_NOTIFICATION_PERMISSION_REQUEST +WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST +WEBKIT_NOTIFICATION_PERMISSION_REQUEST_CLASS +WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST_CLASS +WEBKIT_NOTIFICATION_PERMISSION_REQUEST_GET_CLASS + +<SUBSECTION Private> +WebKitNotificationPermissionRequestPrivate +webkit_notification_permission_request_get_type +</SECTION> + +<SECTION> <FILE>WebKitPolicyDecision</FILE> WebKitPolicyDecision webkit_policy_decision_download @@ -548,6 +741,7 @@ webkit_policy_decision_get_type <FILE>WebKitNavigationPolicyDecision</FILE> WebKitNavigationPolicyDecision WebKitNavigationType +webkit_navigation_policy_decision_get_navigation_action webkit_navigation_policy_decision_get_frame_name webkit_navigation_policy_decision_get_modifiers webkit_navigation_policy_decision_get_mouse_button @@ -598,6 +792,7 @@ webkit_hit_test_result_context_is_link webkit_hit_test_result_context_is_image webkit_hit_test_result_context_is_media webkit_hit_test_result_context_is_editable +webkit_hit_test_result_context_is_selection webkit_hit_test_result_get_link_uri webkit_hit_test_result_get_link_title webkit_hit_test_result_get_link_label @@ -620,6 +815,26 @@ webkit_hit_test_result_get_type </SECTION> <SECTION> +<FILE>WebKitEditorState</FILE> +WebKitEditorState +WebKitEditorTypingAttributes +webkit_editor_state_get_typing_attributes + +<SUBSECTION Standard> +WebKitEditorStateClass +WEBKIT_TYPE_EDITOR_STATE +WEBKIT_EDITOR_STATE +WEBKIT_IS_EDITOR_STATE +WEBKIT_EDITOR_STATE_CLASS +WEBKIT_IS_EDITOR_STATE_CLASS +WEBKIT_EDITOR_STATE_GET_CLASS + +<SUBSECTION Private> +WebKitEditorStatePrivate +webkit_editor_state_get_type +</SECTION> + +<SECTION> <FILE>WebKitPrintOperation</FILE> WebKitPrintOperation WebKitPrintOperationResponse @@ -834,6 +1049,7 @@ WebKitPluginPrivate WebKitWebInspector webkit_web_inspector_get_web_view webkit_web_inspector_get_inspected_uri +webkit_web_inspector_get_can_attach webkit_web_inspector_is_attached webkit_web_inspector_attach webkit_web_inspector_detach @@ -908,6 +1124,8 @@ webkit_context_menu_last webkit_context_menu_get_item_at_position webkit_context_menu_remove webkit_context_menu_remove_all +webkit_context_menu_set_user_data +webkit_context_menu_get_user_data <SUBSECTION Standard> WebKitContextMenuClass @@ -1003,28 +1221,90 @@ webkit_security_manager_get_type </SECTION> <SECTION> -<FILE>WebKitWebViewGroup</FILE> -WebKitWebViewGroup -WebKitInjectedContentFrames -webkit_web_view_group_new -webkit_web_view_group_get_name -webkit_web_view_group_get_settings -webkit_web_view_group_set_settings -webkit_web_view_group_add_user_style_sheet -webkit_web_view_group_remove_all_user_style_sheets +<FILE>WebKitSecurityOrigin</FILE> +WebKitSecurityOrigin +webkit_security_origin_new +webkit_security_origin_new_for_uri +webkit_security_origin_ref +webkit_security_origin_unref +webkit_security_origin_get_protocol +webkit_security_origin_get_host +webkit_security_origin_get_port +webkit_security_origin_is_opaque +webkit_security_origin_to_string + +<SUBSECTION Standard> +WEBKIT_TYPE_SECURITY_ORIGIN + +<SUBSECTION Private> +webkit_security_origin_get_type +</SECTION> + +<SECTION> +<FILE>WebKitWebsiteDataManager</FILE> +WebKitWebsiteDataManager +webkit_website_data_manager_new +webkit_website_data_manager_new_ephemeral +webkit_website_data_manager_is_ephemeral +webkit_website_data_manager_get_base_data_directory +webkit_website_data_manager_get_base_cache_directory +webkit_website_data_manager_get_local_storage_directory +webkit_website_data_manager_get_disk_cache_directory +webkit_website_data_manager_get_offline_application_cache_directory +webkit_website_data_manager_get_indexeddb_directory +webkit_website_data_manager_get_websql_directory +webkit_website_data_manager_get_cookie_manager +webkit_website_data_manager_fetch +webkit_website_data_manager_fetch_finish +webkit_website_data_manager_remove +webkit_website_data_manager_remove_finish +webkit_website_data_manager_clear +webkit_website_data_manager_clear_finish <SUBSECTION Standard> -WebKitWebViewGroupClass -WEBKIT_TYPE_WEB_VIEW_GROUP -WEBKIT_WEB_VIEW_GROUP -WEBKIT_IS_WEB_VIEW_GROUP -WEBKIT_WEB_VIEW_GROUP_CLASS -WEBKIT_IS_WEB_VIEW_GROUP_CLASS -WEBKIT_WEB_VIEW_GROUP_GET_CLASS +WebKitWebsiteDataManagerClass +WEBKIT_TYPE_WEBSITE_DATA_MANAGER +WEBKIT_WEBSITE_DATA_MANAGER +WEBKIT_IS_WEBSITE_DATA_MANAGER +WEBKIT_WEBSITE_DATA_MANAGER_CLASS +WEBKIT_IS_WEBSITE_DATA_MANAGER_CLASS +WEBKIT_WEBSITE_DATA_MANAGER_GET_CLASS <SUBSECTION Private> -WebKitWebViewGroupPrivate -webkit_web_view_group_get_type +WebKitWebsiteDataManagerPrivate +webkit_website_data_manager_get_type +</SECTION> + +<SECTION> +<FILE>WebKitWebsiteData</FILE> +WebKitWebsiteData +WebKitWebsiteDataTypes +webkit_website_data_ref +webkit_website_data_unref +webkit_website_data_get_name +webkit_website_data_get_types +webkit_website_data_get_size + +<SUBSECTION Standard> +WEBKIT_TYPE_WEBSITE_DATA + +<SUBSECTION Private> +webkit_website_data_get_type +</SECTION> + +<SECTION> +<FILE>WebKitNetworkProxySettings</FILE> +WebKitNetworkProxySettings +webkit_network_proxy_settings_new +webkit_network_proxy_settings_copy +webkit_network_proxy_settings_free +webkit_network_proxy_settings_add_proxy_for_scheme + +<SUBSECTION Private> +webkit_network_proxy_settings_get_type + +<SUBSECTION Standard> +WEBKIT_TYPE_NETWORK_NETWORK_PROXY_SETTINGS </SECTION> <SECTION> @@ -1055,6 +1335,7 @@ webkit_web_page_get_dom_document webkit_web_page_get_id webkit_web_page_get_uri webkit_web_page_get_main_frame +webkit_web_page_get_editor <SUBSECTION Standard> WebKitWebPageClass @@ -1071,6 +1352,25 @@ webkit_web_page_get_type </SECTION> <SECTION> +<FILE>WebKitWebEditor</FILE> +WebKitWebEditor +webkit_web_editor_get_page + +<SUBSECTION Standard> +WebKitWebEditorClass +WEBKIT_TYPE_WEB_EDITOR +WEBKIT_WEB_EDITOR +WEBKIT_IS_WEB_EDITOR +WEBKIT_WEB_EDITOR_CLASS +WEBKIT_IS_WEB_EDITOR_CLASS +WEBKIT_WEB_EDITOR_GET_CLASS + +<SUBSECTION Private> +WebKitWebEditorPrivate +webkit_web_editor_get_type +</SECTION> + +<SECTION> <FILE>WebKitFrame</FILE> WebKitFrame webkit_frame_is_main_frame @@ -1113,16 +1413,84 @@ webkit_script_world_get_type </SECTION> <SECTION> -<FILE>WebKitCertificateInfo</FILE> -WebKitCertificateInfo -webkit_certificate_info_copy -webkit_certificate_info_free -webkit_certificate_info_get_tls_certificate -webkit_certificate_info_get_tls_errors +<FILE>WebKitWebHitTestResult</FILE> +WebKitWebHitTestResult +webkit_web_hit_test_result_get_node + +<SUBSECTION Standard> +WebKitWebHitTestResultClass +WEBKIT_TYPE_WEB_HIT_TEST_RESULT +WEBKIT_WEB_HIT_TEST_RESULT +WEBKIT_IS_WEB_HIT_TEST_RESULT +WEBKIT_WEB_HIT_TEST_RESULT_CLASS +WEBKIT_IS_WEB_HIT_TEST_RESULT_CLASS +WEBKIT_WEB_HIT_TEST_RESULT_GET_CLASS + +<SUBSECTION Private> +WebKitWebHitTestResultPrivate +webkit_web_hit_test_result_get_type +</SECTION> + +<SECTION> +<FILE>WebKitConsoleMessage</FILE> +WebKitConsoleMessage +WebKitConsoleMessageSource +WebKitConsoleMessageLevel +webkit_console_message_copy +webkit_console_message_free +webkit_console_message_get_source +webkit_console_message_get_level +webkit_console_message_get_text +webkit_console_message_get_line +webkit_console_message_get_source_id + +<SUBSECTION Standard> +WEBKIT_TYPE_CONSOLE_MESSAGE + +<SUBSECTION Private> +webkit_console_message_get_type +</SECTION> + +<SECTION> +<FILE>WebKitColorChooserRequest</FILE> +WebKitColorChooserRequest +webkit_color_chooser_request_get_rgba +webkit_color_chooser_request_set_rgba +webkit_color_chooser_request_get_element_rectangle +webkit_color_chooser_request_finish +webkit_color_chooser_request_cancel + +<SUBSECTION Standard> +WebKitColorChooserRequestClass +WEBKIT_TYPE_COLOR_CHOOSER_REQUEST +WEBKIT_COLOR_CHOOSER_REQUEST +WEBKIT_IS_COLOR_CHOOSER_REQUEST +WEBKIT_COLOR_CHOOSER_REQUEST_CLASS +WEBKIT_IS_COLOR_CHOOSER_REQUEST_CLASS +WEBKIT_COLOR_CHOOSER_REQUEST_GET_CLASS + +<SUBSECTION Private> +WebKitColorChooserRequestPrivate +webkit_color_chooser_request_get_type +</SECTION> + +<SECTION> +<FILE>WebKitPrintCustomWidget</FILE> +WebKitPrintCustomWidget +webkit_print_custom_widget_new +webkit_print_custom_widget_get_widget +webkit_print_custom_widget_get_title <SUBSECTION Standard> -WEBKIT_TYPE_CERTIFICATE_INFO +WebKitPrintCustomWidgetClass +WEBKIT_TYPE_PRINT_CUSTOM_WIDGET +WEBKIT_PRINT_CUSTOM_WIDGET +WEBKIT_IS_PRINT_CUSTOM_WIDGET +WEBKIT_PRINT_CUSTOM_WIDGET_CLASS +WEBKIT_IS_PRINT_CUSTOM_WIDGET_CLASS +WEBKIT_PRINT_CUSTOM_WIDGET_GET_CLASS <SUBSECTION Private> -webkit_certificate_info_get_type +WebKitPrintCustomWidgetPrivate +webkit_print_custom_widget_get_type </SECTION> diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0.types index 4b583bad9..403051ae7 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0.types @@ -21,10 +21,17 @@ webkit_web_inspector_get_type webkit_uri_scheme_request_get_type webkit_context_menu_get_type webkit_context_menu_item_get_type -webkit_web_view_group_get_type webkit_web_extension_get_type webkit_web_page_get_type webkit_authentication_request_get_type webkit_credential_get_type webkit_frame_get_type webkit_certificate_info_get_type +webkit_user_content_manager_get_type +webkit_web_hit_test_result_get_type +webkit_website_data_manager_get_type +webkit_editor_state_get_type +webkit_install_missing_media_plugins_permission_request_get_type +webkit_console_message_get_type +webkit_web_view_session_state_get_type +webkit_print_custom_widget_get_type diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml index e3cf9a68c..850d7db0b 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml @@ -23,14 +23,20 @@ <xi:include href="xml/WebKitDownload.xml"/> <xi:include href="xml/WebKitPermissionRequest.xml"/> <xi:include href="xml/WebKitGeolocationPermissionRequest.xml"/> + <xi:include href="xml/WebKitInstallMissingMediaPluginsPermissionRequest.xml"/> + <xi:include href="xml/WebKitNavigationAction.xml"/> + <xi:include href="xml/WebKitUserMediaPermissionRequest.xml"/> <xi:include href="xml/WebKitPolicyDecision.xml"/> <xi:include href="xml/WebKitNavigationPolicyDecision.xml"/> <xi:include href="xml/WebKitResponsePolicyDecision.xml"/> <xi:include href="xml/WebKitHitTestResult.xml"/> + <xi:include href="xml/WebKitEditorState.xml"/> + <xi:include href="xml/WebKitPrintCustomWidget.xml"/> <xi:include href="xml/WebKitPrintOperation.xml"/> <xi:include href="xml/WebKitWebResource.xml"/> <xi:include href="xml/WebKitError.xml"/> <xi:include href="xml/WebKitFaviconDatabase.xml"/> + <xi:include href="xml/WebKitColorChooserRequest.xml"/> <xi:include href="xml/WebKitFileChooserRequest.xml"/> <xi:include href="xml/WebKitFindController.xml"/> <xi:include href="xml/WebKitCookieManager.xml"/> @@ -42,8 +48,14 @@ <xi:include href="xml/WebKitContextMenuItem.xml"/> <xi:include href="xml/WebKitFormSubmissionRequest.xml"/> <xi:include href="xml/WebKitSecurityManager.xml"/> - <xi:include href="xml/WebKitWebViewGroup.xml"/> - <xi:include href="xml/WebKitCertificateInfo.xml"/> + <xi:include href="xml/WebKitUserContentManager.xml"/> + <xi:include href="xml/WebKitUserContent.xml"/> + <xi:include href="xml/WebKitNotification.xml"/> + <xi:include href="xml/WebKitNotificationPermissionRequest.xml"/> + <xi:include href="xml/WebKitSecurityOrigin.xml"/> + <xi:include href="xml/WebKitWebsiteDataManager.xml"/> + <xi:include href="xml/WebKitWebsiteData.xml"/> + <xi:include href="xml/WebKitNetworkProxySettings.xml"/> </chapter> <chapter> @@ -52,21 +64,59 @@ <xi:include href="xml/WebKitWebPage.xml"/> <xi:include href="xml/WebKitFrame.xml"/> <xi:include href="xml/WebKitScriptWorld.xml"/> + <xi:include href="xml/WebKitWebHitTestResult.xml"/> + <xi:include href="xml/WebKitWebEditor.xml"/> + <xi:include href="xml/WebKitConsoleMessage.xml"/> </chapter> <index id="index-all"> <title>Index</title> </index> - + + <index id="api-index-deprecated" role="deprecated"> + <title>Index of deprecated symbols</title> + <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-2-2" role="2.2"> <title>Index of new symbols in 2.2</title> <xi:include href="xml/api-index-2.2.xml"><xi:fallback /></xi:include> - </index> + </index> <index id="api-index-2-4" role="2.4"> <title>Index of new symbols in 2.4</title> <xi:include href="xml/api-index-2.4.xml"><xi:fallback /></xi:include> </index> + <index id="api-index-2-6" role="2.6"> + <title>Index of new symbols in 2.6</title> + <xi:include href="xml/api-index-2.6.xml"><xi:fallback /></xi:include> + </index> + + <index id="api-index-2-8" role="2.8"> + <title>Index of new symbols in 2.8</title> + <xi:include href="xml/api-index-2.8.xml"><xi:fallback /></xi:include> + </index> + + <index id="api-index-2-10" role="2.10"> + <title>Index of new symbols in 2.10</title> + <xi:include href="xml/api-index-2.10.xml"><xi:fallback /></xi:include> + </index> + + <index id="api-index-2-12" role="2.12"> + <title>Index of new symbols in 2.12</title> + <xi:include href="xml/api-index-2.12.xml"><xi:fallback /></xi:include> + </index> + + <index id="api-index-2-14" role="2.14"> + <title>Index of new symbols in 2.14</title> + <xi:include href="xml/api-index-2.14.xml"><xi:fallback /></xi:include> + </index> + + <index id="api-index-2-16" role="2.16"> + <title>Index of new symbols in 2.16</title> + <xi:include href="xml/api-index-2.16.xml"><xi:fallback /></xi:include> + </index> + <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include> </book> diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2.h b/Source/WebKit2/UIProcess/API/gtk/webkit2.h index c18538a63..63dd1d5be 100644 --- a/Source/WebKit2/UIProcess/API/gtk/webkit2.h +++ b/Source/WebKit2/UIProcess/API/gtk/webkit2.h @@ -30,7 +30,6 @@ #include <webkit2/WebKitAuthenticationRequest.h> #include <webkit2/WebKitBackForwardList.h> #include <webkit2/WebKitBackForwardListItem.h> -#include <webkit2/WebKitCertificateInfo.h> #include <webkit2/WebKitContextMenu.h> #include <webkit2/WebKitContextMenuActions.h> #include <webkit2/WebKitContextMenuItem.h> @@ -39,36 +38,52 @@ #include <webkit2/WebKitDefines.h> #include <webkit2/WebKitDownload.h> #include <webkit2/WebKitEditingCommands.h> +#include <webkit2/WebKitEditorState.h> #include <webkit2/WebKitEnumTypes.h> #include <webkit2/WebKitError.h> #include <webkit2/WebKitFaviconDatabase.h> +#include <webkit2/WebKitColorChooserRequest.h> #include <webkit2/WebKitFileChooserRequest.h> #include <webkit2/WebKitFindController.h> #include <webkit2/WebKitFormSubmissionRequest.h> #include <webkit2/WebKitGeolocationPermissionRequest.h> #include <webkit2/WebKitHitTestResult.h> +#include <webkit2/WebKitInstallMissingMediaPluginsPermissionRequest.h> #include <webkit2/WebKitJavascriptResult.h> #include <webkit2/WebKitMimeInfo.h> +#include <webkit2/WebKitNavigationAction.h> #include <webkit2/WebKitNavigationPolicyDecision.h> +#include <webkit2/WebKitNetworkProxySettings.h> +#include <webkit2/WebKitNotification.h> +#include <webkit2/WebKitNotificationPermissionRequest.h> #include <webkit2/WebKitPermissionRequest.h> #include <webkit2/WebKitPlugin.h> +#include <webkit2/WebKitPrintCustomWidget.h> #include <webkit2/WebKitPrintOperation.h> #include <webkit2/WebKitResponsePolicyDecision.h> #include <webkit2/WebKitScriptDialog.h> #include <webkit2/WebKitSecurityManager.h> +#include <webkit2/WebKitSecurityOrigin.h> #include <webkit2/WebKitSettings.h> #include <webkit2/WebKitURIRequest.h> #include <webkit2/WebKitURIResponse.h> #include <webkit2/WebKitURISchemeRequest.h> +#include <webkit2/WebKitUserContent.h> +#include <webkit2/WebKitUserContentManager.h> +#include <webkit2/WebKitUserMediaPermissionRequest.h> #include <webkit2/WebKitVersion.h> #include <webkit2/WebKitWebContext.h> #include <webkit2/WebKitWebInspector.h> #include <webkit2/WebKitWebResource.h> #include <webkit2/WebKitWebView.h> #include <webkit2/WebKitWebViewBase.h> -#include <webkit2/WebKitWebViewGroup.h> +#include <webkit2/WebKitWebViewSessionState.h> +#include <webkit2/WebKitWebsiteData.h> +#include <webkit2/WebKitWebsiteDataManager.h> #include <webkit2/WebKitWindowProperties.h> +#include <webkit2/WebKitAutocleanups.h> + #undef __WEBKIT2_H_INSIDE__ #endif /* __WEBKIT2_H__ */ diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list b/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list index e1cfe0721..d638661f4 100644 --- a/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list +++ b/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list @@ -1,6 +1,5 @@ BOOLEAN:BOXED BOOLEAN:BOXED,STRING -BOOLEAN:ENUM,STRING,POINTER BOOLEAN:OBJECT BOOLEAN:OBJECT,BOXED,OBJECT BOOLEAN:OBJECT,ENUM |