summaryrefslogtreecommitdiffstats
path: root/WebKit/win/WebView.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/win/WebView.cpp')
-rw-r--r--WebKit/win/WebView.cpp828
1 files changed, 685 insertions, 143 deletions
diff --git a/WebKit/win/WebView.cpp b/WebKit/win/WebView.cpp
index b51af67..d98d390 100644
--- a/WebKit/win/WebView.cpp
+++ b/WebKit/win/WebView.cpp
@@ -31,17 +31,17 @@
#include "DOMCoreClasses.h"
#include "MarshallingHelpers.h"
#include "SoftLinking.h"
+#include "WebBackForwardList.h"
+#include "WebChromeClient.h"
+#include "WebContextMenuClient.h"
+#include "WebCoreTextRenderer.h"
#include "WebDatabaseManager.h"
#include "WebDocumentLoader.h"
#include "WebDownload.h"
+#include "WebDragClient.h"
#include "WebEditorClient.h"
#include "WebElementPropertyBag.h"
#include "WebFrame.h"
-#include "WebBackForwardList.h"
-#include "WebChromeClient.h"
-#include "WebContextMenuClient.h"
-#include "WebCoreTextRenderer.h"
-#include "WebDragClient.h"
#include "WebIconDatabase.h"
#include "WebInspector.h"
#include "WebInspectorClient.h"
@@ -50,7 +50,9 @@
#include "WebKitSystemBits.h"
#include "WebMutableURLRequest.h"
#include "WebNotificationCenter.h"
+#include "WebPluginHalterClient.h"
#include "WebPreferences.h"
+#include "WebScriptWorld.h"
#include "WindowsTouch.h"
#pragma warning( push, 0 )
#include <WebCore/ApplicationCacheStorage.h>
@@ -88,15 +90,18 @@
#include <WebCore/MIMETypeRegistry.h>
#include <WebCore/Page.h>
#include <WebCore/PageCache.h>
+#include <WebCore/PageGroup.h>
#include <WebCore/PlatformKeyboardEvent.h>
#include <WebCore/PlatformMouseEvent.h>
#include <WebCore/PlatformWheelEvent.h>
#include <WebCore/PluginDatabase.h>
#include <WebCore/PluginInfoStore.h>
#include <WebCore/PluginView.h>
+#include <WebCore/PopupMenu.h>
#include <WebCore/ProgressTracker.h>
#include <WebCore/RenderTheme.h>
#include <WebCore/RenderView.h>
+#include <WebCore/RenderWidget.h>
#include <WebCore/ResourceHandle.h>
#include <WebCore/ResourceHandleClient.h>
#include <WebCore/ScriptValue.h>
@@ -128,6 +133,7 @@
#endif
#include <wtf/HashSet.h>
+#include <comutil.h>
#include <dimm.h>
#include <oleacc.h>
#include <ShlObj.h>
@@ -145,9 +151,8 @@ SOFT_LINK_OPTIONAL(Uxtheme, EndPanningFeedback, BOOL, WINAPI, (HWND, BOOL));
SOFT_LINK_OPTIONAL(Uxtheme, UpdatePanningFeedback, BOOL, WINAPI, (HWND, LONG, LONG, BOOL));
using namespace WebCore;
+using namespace std;
using JSC::JSLock;
-using std::min;
-using std::max;
static HMODULE accessibilityLib;
static HashSet<WebView*> pendingDeleteBackingStoreSet;
@@ -266,7 +271,6 @@ static const int maxToolTipWidth = 250;
static const int delayBeforeDeletingBackingStoreMsec = 5000;
static ATOM registerWebView();
-static LRESULT CALLBACK WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static void initializeStaticObservers();
@@ -290,34 +294,37 @@ enum {
bool WebView::s_allowSiteSpecificHacks = false;
WebView::WebView()
-: m_refCount(0)
-, m_hostWindow(0)
-, m_viewWindow(0)
-, m_mainFrame(0)
-, m_page(0)
-, m_hasCustomDropTarget(false)
-, m_useBackForwardList(true)
-, m_userAgentOverridden(false)
-, m_zoomMultiplier(1.0f)
-, m_mouseActivated(false)
-, m_dragData(0)
-, m_currentCharacterCode(0)
-, m_isBeingDestroyed(false)
-, m_paintCount(0)
-, m_hasSpellCheckerDocumentTag(false)
-, m_smartInsertDeleteEnabled(false)
-, m_didClose(false)
-, m_inIMEComposition(0)
-, m_toolTipHwnd(0)
-, m_closeWindowTimer(this, &WebView::closeWindowTimerFired)
-, m_topLevelParent(0)
-, m_deleteBackingStoreTimerActive(false)
-, m_transparent(false)
-, m_selectTrailingWhitespaceEnabled(false)
-, m_lastPanX(0)
-, m_lastPanY(0)
-, m_xOverpan(0)
-, m_yOverpan(0)
+ : m_refCount(0)
+ , m_hostWindow(0)
+ , m_viewWindow(0)
+ , m_mainFrame(0)
+ , m_page(0)
+ , m_hasCustomDropTarget(false)
+ , m_useBackForwardList(true)
+ , m_userAgentOverridden(false)
+ , m_zoomMultiplier(1.0f)
+ , m_mouseActivated(false)
+ , m_dragData(0)
+ , m_currentCharacterCode(0)
+ , m_isBeingDestroyed(false)
+ , m_paintCount(0)
+ , m_hasSpellCheckerDocumentTag(false)
+ , m_smartInsertDeleteEnabled(false)
+ , m_didClose(false)
+ , m_inIMEComposition(0)
+ , m_toolTipHwnd(0)
+ , m_closeWindowTimer(this, &WebView::closeWindowTimerFired)
+ , m_topLevelParent(0)
+ , m_deleteBackingStoreTimerActive(false)
+ , m_transparent(false)
+ , m_selectTrailingWhitespaceEnabled(false)
+ , m_lastPanX(0)
+ , m_lastPanY(0)
+ , m_xOverpan(0)
+ , m_yOverpan(0)
+#if USE(ACCELERATED_COMPOSITING)
+ , m_isAcceleratedCompositing(false)
+#endif
{
JSC::initializeThreading();
@@ -613,6 +620,12 @@ HRESULT STDMETHODCALLTYPE WebView::close()
m_didClose = true;
+#if USE(ACCELERATED_COMPOSITING)
+ setAcceleratedCompositing(false);
+#endif
+
+ WebNotificationCenter::defaultCenterInternal()->postNotificationName(_bstr_t(WebViewWillCloseNotification).GetBSTR(), static_cast<IWebView*>(this), 0);
+
if (m_uiDelegatePrivate)
m_uiDelegatePrivate->webViewClosing(this);
@@ -634,10 +647,12 @@ HRESULT STDMETHODCALLTYPE WebView::close()
setEditingDelegate(0);
setFrameLoadDelegate(0);
setFrameLoadDelegatePrivate(0);
+ setHistoryDelegate(0);
setPolicyDelegate(0);
setResourceLoadDelegate(0);
setUIDelegate(0);
setFormDelegate(0);
+ setPluginHalterDelegate(0);
if (m_webInspector)
m_webInspector->webViewClosed();
@@ -668,6 +683,11 @@ HRESULT STDMETHODCALLTYPE WebView::close()
void WebView::repaint(const WebCore::IntRect& windowRect, bool contentChanged, bool immediate, bool repaintContentOnly)
{
+#if USE(ACCELERATED_COMPOSITING)
+ if (isAcceleratedCompositing())
+ setRootLayerNeedsDisplay();
+#endif
+
if (!repaintContentOnly) {
RECT rect = windowRect;
::InvalidateRect(m_viewWindow, &rect, false);
@@ -719,6 +739,10 @@ bool WebView::ensureBackingStore()
void WebView::addToDirtyRegion(const IntRect& dirtyRect)
{
+ // FIXME: We want an assert here saying that the dirtyRect is inside the clienRect,
+ // but it was being hit during our layout tests, and is being investigated in
+ // http://webkit.org/b/29350.
+
HRGN newRegion = ::CreateRectRgn(dirtyRect.x(), dirtyRect.y(),
dirtyRect.right(), dirtyRect.bottom());
addToDirtyRegion(newRegion);
@@ -782,7 +806,6 @@ void WebView::scrollBackingStore(FrameView* frameView, int dx, int dy, const Int
// Clean up.
::DeleteDC(bitmapDC);
::ReleaseDC(m_viewWindow, windowDC);
-
}
// This emulates the Mac smarts for painting rects intelligently. This is very
@@ -915,34 +938,28 @@ void WebView::paint(HDC dc, LPARAM options)
// Update our backing store if needed.
updateBackingStore(frameView, bitmapDC, backingStoreCompletelyDirty, windowsToPaint);
- // Now we blit the updated backing store
- IntRect windowDirtyRect = rcPaint;
-
- // Apply the same heuristic for this update region too.
- Vector<IntRect> blitRects;
- if (region && regionType == COMPLEXREGION)
- getUpdateRects(region.get(), windowDirtyRect, blitRects);
- else
- blitRects.append(windowDirtyRect);
+#if USE(ACCELERATED_COMPOSITING)
+ if (!isAcceleratedCompositing()) {
+#endif
+ // Now we blit the updated backing store
+ IntRect windowDirtyRect = rcPaint;
+
+ // Apply the same heuristic for this update region too.
+ Vector<IntRect> blitRects;
+ if (region && regionType == COMPLEXREGION)
+ getUpdateRects(region.get(), windowDirtyRect, blitRects);
+ else
+ blitRects.append(windowDirtyRect);
- for (unsigned i = 0; i < blitRects.size(); ++i)
- paintIntoWindow(bitmapDC, hdc, blitRects[i]);
+ for (unsigned i = 0; i < blitRects.size(); ++i)
+ paintIntoWindow(bitmapDC, hdc, blitRects[i]);
+#if USE(ACCELERATED_COMPOSITING)
+ } else
+ updateRootLayerContents();
+#endif
::DeleteDC(bitmapDC);
- // Paint the gripper.
- COMPtr<IWebUIDelegate> ui;
- if (SUCCEEDED(uiDelegate(&ui))) {
- COMPtr<IWebUIDelegatePrivate> uiPrivate;
- if (SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegatePrivate, (void**)&uiPrivate))) {
- RECT r;
- if (SUCCEEDED(uiPrivate->webViewResizerRect(this, &r))) {
- LOCAL_GDI_COUNTER(2, __FUNCTION__" webViewDrawResizer delegate call");
- uiPrivate->webViewDrawResizer(this, hdc, (frameView->containsScrollbarsAvoidingResizer() ? true : false), &r);
- }
- }
- }
-
if (!dc)
EndPaint(m_viewWindow, &ps);
@@ -958,6 +975,10 @@ void WebView::paintIntoBackingStore(FrameView* frameView, HDC bitmapDC, const In
{
LOCAL_GDI_COUNTER(0, __FUNCTION__);
+ // FIXME: We want an assert here saying that the dirtyRect is inside the clienRect,
+ // but it was being hit during our layout tests, and is being investigated in
+ // http://webkit.org/b/29350.
+
RECT rect = dirtyRect;
#if FLASH_BACKING_STORE_REDRAW
@@ -977,6 +998,11 @@ void WebView::paintIntoBackingStore(FrameView* frameView, HDC bitmapDC, const In
gc.clearRect(dirtyRect);
else
FillRect(bitmapDC, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
+
+ COMPtr<IWebUIDelegatePrivate2> uiPrivate(Query, m_uiDelegate);
+ if (uiPrivate)
+ uiPrivate->drawBackground(this, reinterpret_cast<OLE_HANDLE>(bitmapDC), &rect);
+
if (frameView && frameView->frame() && frameView->frame()->contentRenderer()) {
gc.clip(dirtyRect);
frameView->paint(&gc, dirtyRect);
@@ -1270,12 +1296,6 @@ bool WebView::handleMouseEvent(UINT message, WPARAM wParam, LPARAM lParam)
abs(globalPrevPoint.y() - mouseEvent.pos().y()) < ::GetSystemMetrics(SM_CYDOUBLECLK);
LONG messageTime = ::GetMessageTime();
- if (inResizer(position)) {
- if (m_uiDelegatePrivate)
- m_uiDelegatePrivate->webViewSendResizeMessage(message, wParam, position);
- return true;
- }
-
bool handled = false;
if (message == WM_LBUTTONDOWN || message == WM_MBUTTONDOWN || message == WM_RBUTTONDOWN) {
@@ -1349,25 +1369,65 @@ bool WebView::gestureNotify(WPARAM wParam, LPARAM lParam)
// If we don't have this function, we shouldn't be receiving this message
ASSERT(SetGestureConfigPtr());
- DWORD dwPanWant;
- DWORD dwPanBlock;
-
- // Translate gesture location to client to hit test on scrollbars
+ bool hitScrollbar = false;
POINT gestureBeginPoint = {gn->ptsLocation.x, gn->ptsLocation.y};
- IntPoint eventHandlerPoint = m_page->mainFrame()->view()->screenToContents(gestureBeginPoint);
+ HitTestRequest request(HitTestRequest::ReadOnly);
+ for (Frame* childFrame = m_page->mainFrame(); childFrame; childFrame = EventHandler::subframeForTargetNode(m_gestureTargetNode.get())) {
+ FrameView* frameView = childFrame->view();
+ if (!frameView)
+ break;
+ RenderView* renderView = childFrame->document()->renderView();
+ if (!renderView)
+ break;
+ RenderLayer* layer = renderView->layer();
+ if (!layer)
+ break;
+
+ HitTestResult result(frameView->screenToContents(gestureBeginPoint));
+ layer->hitTest(request, result);
+ m_gestureTargetNode = result.innerNode();
- HitTestResult scrollbarTest = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(eventHandlerPoint, true, false, ShouldHitTestScrollbars);
+ if (!hitScrollbar)
+ hitScrollbar = result.scrollbar();
+ }
+
+ if (!hitScrollbar) {
+ // The hit testing above won't detect if we've hit the main frame's vertical scrollbar. Check that manually now.
+ RECT webViewRect;
+ GetWindowRect(m_viewWindow, &webViewRect);
+ hitScrollbar = view->verticalScrollbar() && (gestureBeginPoint.x > (webViewRect.right - view->verticalScrollbar()->theme()->scrollbarThickness()));
+ }
- if (eventHandlerPoint.x() > view->visibleWidth() || scrollbarTest.scrollbar()) {
- // We are in the scrollbar, turn off panning, need to be able to drag the scrollbar
- dwPanWant = GC_PAN | GC_PAN_WITH_INERTIA | GC_PAN_WITH_GUTTER;
- dwPanBlock = GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY | GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
+ bool canBeScrolled = false;
+ if (m_gestureTargetNode) {
+ for (RenderObject* renderer = m_gestureTargetNode->renderer(); renderer; renderer = renderer->parent()) {
+ if (renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()) {
+ canBeScrolled = true;
+ break;
+ }
+ }
+ }
+
+ // We always allow two-fingered panning with inertia and a gutter (which limits movement to one
+ // direction in most cases).
+ DWORD dwPanWant = GC_PAN | GC_PAN_WITH_INERTIA | GC_PAN_WITH_GUTTER;
+ // We never allow single-fingered horizontal panning. That gesture is reserved for creating text
+ // selections. This matches IE.
+ DWORD dwPanBlock = GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
+
+ if (hitScrollbar || !canBeScrolled) {
+ // The part of the page under the gesture can't be scrolled, or the gesture is on a scrollbar.
+ // Disallow single-fingered vertical panning in this case, too, so we'll fall back to the default
+ // behavior (which allows the scrollbar thumb to be dragged, text selections to be made, etc.).
+ dwPanBlock |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
} else {
- dwPanWant = GC_PAN | GC_PAN_WITH_SINGLE_FINGER_VERTICALLY | GC_PAN_WITH_INERTIA | GC_PAN_WITH_GUTTER;
- dwPanBlock = GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
+ // The part of the page the gesture is under can be scrolled, and we're not under a scrollbar.
+ // Allow single-fingered vertical panning in this case, so the user will be able to pan the page
+ // with one or two fingers.
+ dwPanWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
}
- GESTURECONFIG gc = { GID_PAN, dwPanWant , dwPanBlock } ;
+ GESTURECONFIG gc = { GID_PAN, dwPanWant, dwPanBlock };
return SetGestureConfigPtr()(m_viewWindow, 0, 1, &gc, sizeof(GESTURECONFIG));
}
@@ -1390,21 +1450,20 @@ bool WebView::gesture(WPARAM wParam, LPARAM lParam)
m_lastPanX = gi.ptsLocation.x;
m_lastPanY = gi.ptsLocation.y;
- CloseGestureInfoHandlePtr()(gestureHandle);
+ break;
+ case GID_END:
+ m_gestureTargetNode = 0;
break;
case GID_PAN: {
// Where are the fingers currently?
long currentX = gi.ptsLocation.x;
long currentY = gi.ptsLocation.y;
-
// How far did we pan in each direction?
long deltaX = currentX - m_lastPanX;
long deltaY = currentY - m_lastPanY;
-
// Calculate the overpan for window bounce
m_yOverpan -= m_lastPanY - currentY;
m_xOverpan -= m_lastPanX - currentX;
-
// Update our class variables with updated values
m_lastPanX = currentX;
m_lastPanY = currentY;
@@ -1414,10 +1473,13 @@ bool WebView::gesture(WPARAM wParam, LPARAM lParam)
CloseGestureInfoHandlePtr()(gestureHandle);
return false;
}
- // Represent the pan gesture as a mouse wheel event
- PlatformWheelEvent wheelEvent(m_viewWindow, FloatSize(deltaX, deltaY), FloatPoint(currentX, currentY));
- coreFrame->eventHandler()->handleWheelEvent(wheelEvent);
+ if (!m_gestureTargetNode || !m_gestureTargetNode->renderer())
+ return false;
+
+ // We negate here since panning up moves the content up, but moves the scrollbar down.
+ m_gestureTargetNode->renderer()->enclosingLayer()->scrollByRecursively(-deltaX, -deltaY);
+
if (!(UpdatePanningFeedbackPtr() && BeginPanningFeedbackPtr() && EndPanningFeedbackPtr())) {
CloseGestureInfoHandlePtr()(gestureHandle);
return true;
@@ -1434,7 +1496,7 @@ bool WebView::gesture(WPARAM wParam, LPARAM lParam)
ScrollView* view = coreFrame->view();
if (!view) {
CloseGestureInfoHandlePtr()(gestureHandle);
- return false;
+ return true;
}
Scrollbar* vertScrollbar = view->verticalScrollbar();
if (!vertScrollbar) {
@@ -1442,22 +1504,26 @@ bool WebView::gesture(WPARAM wParam, LPARAM lParam)
return true;
}
- // FIXME: Support Horizontal Window Bounce
+ // FIXME: Support Horizontal Window Bounce. <https://webkit.org/b/28500>.
+ // FIXME: If the user starts panning down after a window bounce has started, the window doesn't bounce back
+ // until they release their finger. <https://webkit.org/b/28501>.
if (vertScrollbar->currentPos() == 0)
UpdatePanningFeedbackPtr()(m_viewWindow, 0, m_yOverpan, gi.dwFlags & GF_INERTIA);
else if (vertScrollbar->currentPos() >= vertScrollbar->maximum())
UpdatePanningFeedbackPtr()(m_viewWindow, 0, m_yOverpan, gi.dwFlags & GF_INERTIA);
CloseGestureInfoHandlePtr()(gestureHandle);
- break;
+ return true;
}
default:
- // We have encountered an unknown gesture - return false to pass it to DefWindowProc
- CloseGestureInfoHandlePtr()(gestureHandle);
break;
}
- return true;
+ // If we get to this point, the gesture has not been handled. We forward
+ // the call to DefWindowProc by returning false, and we don't need to
+ // to call CloseGestureInfoHandle.
+ // http://msdn.microsoft.com/en-us/library/dd353228(VS.85).aspx
+ return false;
}
bool WebView::mouseWheel(WPARAM wParam, LPARAM lParam, bool isMouseHWheel)
@@ -1473,6 +1539,23 @@ bool WebView::mouseWheel(WPARAM wParam, LPARAM lParam, bool isMouseHWheel)
makeTextLarger(0);
return true;
}
+
+ // FIXME: This doesn't fix https://bugs.webkit.org/show_bug.cgi?id=28217. This only fixes https://bugs.webkit.org/show_bug.cgi?id=28203.
+ HWND focusedWindow = GetFocus();
+ if (focusedWindow && focusedWindow != m_viewWindow) {
+ // Our focus is on a different hwnd, see if it's a PopupMenu and if so, set the focus back on us (which will hide the popup).
+ TCHAR className[256];
+
+ // Make sure truncation won't affect the comparison.
+ ASSERT(ARRAYSIZE(className) > _tcslen(PopupMenu::popupClassName()));
+
+ if (GetClassName(focusedWindow, className, ARRAYSIZE(className)) && !_tcscmp(className, PopupMenu::popupClassName())) {
+ // We don't let the WebView scroll here for two reasons - 1) To match Firefox behavior, 2) If we do scroll, we lose the
+ // focus ring around the select menu.
+ SetFocus(m_viewWindow);
+ return true;
+ }
+ }
PlatformWheelEvent wheelEvent(m_viewWindow, wParam, lParam, isMouseHWheel);
Frame* coreFrame = core(m_mainFrame);
@@ -1740,22 +1823,7 @@ bool WebView::keyPress(WPARAM charCode, LPARAM keyData, bool systemKeyDown)
return frame->eventHandler()->keyEvent(keyEvent);
}
-bool WebView::inResizer(LPARAM lParam)
-{
- if (!m_uiDelegatePrivate)
- return false;
-
- RECT r;
- if (FAILED(m_uiDelegatePrivate->webViewResizerRect(this, &r)))
- return false;
-
- POINT pt;
- pt.x = LOWORD(lParam);
- pt.y = HIWORD(lParam);
- return !!PtInRect(&r, pt);
-}
-
-static bool registerWebViewWindowClass()
+bool WebView::registerWebViewWindowClass()
{
static bool haveRegisteredWindowClass = false;
if (haveRegisteredWindowClass)
@@ -1799,7 +1867,7 @@ static HWND findTopLevelParent(HWND window)
return 0;
}
-static LRESULT CALLBACK WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+LRESULT CALLBACK WebView::WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = 0;
LONG_PTR longPtr = GetWindowLongPtr(hWnd, 0);
@@ -1834,8 +1902,8 @@ static LRESULT CALLBACK WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, L
webView->paint((HDC)wParam, lParam);
break;
case WM_DESTROY:
- webView->close();
webView->setIsBeingDestroyed();
+ webView->close();
webView->revokeDragDrop();
break;
case WM_GESTURENOTIFY:
@@ -1891,22 +1959,31 @@ static LRESULT CALLBACK WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, L
if (lParam != 0) {
webView->deleteBackingStore();
+#if USE(ACCELERATED_COMPOSITING)
+ if (webView->isAcceleratedCompositing())
+ webView->resizeLayerRenderer();
+#endif
if (Frame* coreFrame = core(mainFrameImpl))
coreFrame->view()->resize(LOWORD(lParam), HIWORD(lParam));
}
break;
case WM_SHOWWINDOW:
lResult = DefWindowProc(hWnd, message, wParam, lParam);
- if (wParam == 0)
+ if (wParam == 0) {
// The window is being hidden (e.g., because we switched tabs).
// Null out our backing store.
webView->deleteBackingStore();
+ }
+#if USE(ACCELERATED_COMPOSITING)
+ else if (webView->isAcceleratedCompositing())
+ webView->layerRendererBecameVisible();
+#endif
break;
case WM_SETFOCUS: {
COMPtr<IWebUIDelegate> uiDelegate;
COMPtr<IWebUIDelegatePrivate> uiDelegatePrivate;
- if (SUCCEEDED(webView->uiDelegate(&uiDelegate)) && uiDelegate &&
- SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegatePrivate, (void**) &uiDelegatePrivate)) && uiDelegatePrivate)
+ if (SUCCEEDED(webView->uiDelegate(&uiDelegate)) && uiDelegate
+ && SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegatePrivate, (void**) &uiDelegatePrivate)) && uiDelegatePrivate)
uiDelegatePrivate->webViewReceivedFocus(webView);
FocusController* focusController = webView->page()->focusController();
@@ -1925,8 +2002,8 @@ static LRESULT CALLBACK WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, L
COMPtr<IWebUIDelegate> uiDelegate;
COMPtr<IWebUIDelegatePrivate> uiDelegatePrivate;
HWND newFocusWnd = reinterpret_cast<HWND>(wParam);
- if (SUCCEEDED(webView->uiDelegate(&uiDelegate)) && uiDelegate &&
- SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegatePrivate, (void**) &uiDelegatePrivate)) && uiDelegatePrivate)
+ if (SUCCEEDED(webView->uiDelegate(&uiDelegate)) && uiDelegate
+ && SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegatePrivate, (void**) &uiDelegatePrivate)) && uiDelegatePrivate)
uiDelegatePrivate->webViewLostFocus(webView, (OLE_HANDLE)(ULONG64)newFocusWnd);
FocusController* focusController = webView->page()->focusController();
@@ -1935,6 +2012,10 @@ static LRESULT CALLBACK WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, L
// Send blur events unless we're losing focus to a child of ours.
if (!IsChild(hWnd, newFocusWnd))
focusController->setFocused(false);
+
+ // If we are pan-scrolling when we lose focus, stop the pan scrolling.
+ frame->eventHandler()->stopAutoscrollTimer();
+
break;
}
case WM_WINDOWPOSCHANGED:
@@ -1986,7 +2067,11 @@ static LRESULT CALLBACK WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, L
RECT windowRect;
::GetClientRect(hWnd, &windowRect);
::InvalidateRect(hWnd, &windowRect, false);
- }
+#if USE(ACCELERATED_COMPOSITING)
+ if (webView->isAcceleratedCompositing())
+ webView->setRootLayerNeedsDisplay();
+#endif
+ }
break;
case WM_MOUSEACTIVATE:
webView->setMouseActivated(true);
@@ -2001,9 +2086,9 @@ static LRESULT CALLBACK WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, L
if (lpMsg->message == WM_KEYDOWN)
keyCode = (UINT) lpMsg->wParam;
}
- if (SUCCEEDED(webView->uiDelegate(&uiDelegate)) && uiDelegate &&
- SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegatePrivate, (void**) &uiDelegatePrivate)) && uiDelegatePrivate &&
- SUCCEEDED(uiDelegatePrivate->webViewGetDlgCode(webView, keyCode, &dlgCode)))
+ if (SUCCEEDED(webView->uiDelegate(&uiDelegate)) && uiDelegate
+ && SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegatePrivate, (void**) &uiDelegatePrivate)) && uiDelegatePrivate
+ && SUCCEEDED(uiDelegatePrivate->webViewGetDlgCode(webView, keyCode, &dlgCode)))
return dlgCode;
handled = false;
break;
@@ -2281,13 +2366,8 @@ HRESULT STDMETHODCALLTYPE WebView::initWithFrame(
registerWebViewWindowClass();
- if (!::IsWindow(m_hostWindow)) {
- ASSERT_NOT_REACHED();
- return E_FAIL;
- }
-
- m_viewWindow = CreateWindowEx(0, kWebViewWindowClassName, 0, WS_CHILD | WS_CLIPCHILDREN,
- frame.left, frame.top, frame.right - frame.left, frame.bottom - frame.top, m_hostWindow, 0, gInstance, 0);
+ m_viewWindow = CreateWindowEx(0, kWebViewWindowClassName, 0, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
+ frame.left, frame.top, frame.right - frame.left, frame.bottom - frame.top, m_hostWindow ? m_hostWindow : HWND_MESSAGE, 0, gInstance, 0);
ASSERT(::IsWindow(m_viewWindow));
hr = registerDragDrop();
@@ -2310,7 +2390,11 @@ HRESULT STDMETHODCALLTYPE WebView::initWithFrame(
Settings::setShouldPaintNativeControls(shouldPaintNativeControls);
#endif
- m_page = new Page(new WebChromeClient(this), new WebContextMenuClient(this), new WebEditorClient(this), new WebDragClient(this), new WebInspectorClient(this));
+ BOOL useHighResolutionTimer;
+ if (SUCCEEDED(m_preferences->shouldUseHighResolutionTimers(&useHighResolutionTimer)))
+ Settings::setShouldUseHighResolutionTimers(useHighResolutionTimer);
+
+ m_page = new Page(new WebChromeClient(this), new WebContextMenuClient(this), new WebEditorClient(this), new WebDragClient(this), new WebInspectorClient(this), new WebPluginHalterClient(this));
BSTR localStoragePath;
if (SUCCEEDED(m_preferences->localStorageDatabasePath(&localStoragePath))) {
@@ -2818,12 +2902,13 @@ HRESULT STDMETHODCALLTYPE WebView::stringByEvaluatingJavaScriptFromString(
if (!coreFrame)
return E_FAIL;
- JSC::JSValue scriptExecutionResult = coreFrame->loader()->executeScript(WebCore::String(script), true).jsValue();
+ JSC::JSValue scriptExecutionResult = coreFrame->script()->executeScript(WebCore::String(script), true).jsValue();
if (!scriptExecutionResult)
return E_FAIL;
else if (scriptExecutionResult.isString()) {
JSLock lock(JSC::SilenceAssertionsOnly);
- *result = BString(String(scriptExecutionResult.getString()));
+ JSC::ExecState* exec = coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec();
+ *result = BString(String(scriptExecutionResult.getString(exec)));
}
return S_OK;
@@ -2952,8 +3037,17 @@ HRESULT STDMETHODCALLTYPE WebView::setHostWindow(
/* [in] */ OLE_HANDLE oleWindow)
{
HWND window = (HWND)(ULONG64)oleWindow;
- if (m_viewWindow && window)
- SetParent(m_viewWindow, window);
+ if (m_viewWindow) {
+ if (window)
+ SetParent(m_viewWindow, window);
+ else if (!isBeingDestroyed()) {
+ // Turn the WebView into a message-only window so it will no longer be a child of the
+ // old host window and will be hidden from screen. We only do this when
+ // isBeingDestroyed() is false because doing this while handling WM_DESTROY can leave
+ // m_viewWindow in a weird state (see <http://webkit.org/b/29337>).
+ SetParent(m_viewWindow, HWND_MESSAGE);
+ }
+ }
m_hostWindow = window;
@@ -3304,10 +3398,34 @@ HRESULT STDMETHODCALLTYPE WebView::setMainFrameURL(
}
HRESULT STDMETHODCALLTYPE WebView::mainFrameURL(
- /* [retval][out] */ BSTR* /*urlString*/)
+ /* [retval][out] */ BSTR* urlString)
{
- ASSERT_NOT_REACHED();
- return E_NOTIMPL;
+ if (!urlString)
+ return E_POINTER;
+
+ if (!m_mainFrame)
+ return E_FAIL;
+
+ COMPtr<IWebDataSource> dataSource;
+
+ if (FAILED(m_mainFrame->provisionalDataSource(&dataSource))) {
+ if (FAILED(m_mainFrame->dataSource(&dataSource)))
+ return E_FAIL;
+ }
+
+ if (!dataSource) {
+ *urlString = 0;
+ return S_OK;
+ }
+
+ COMPtr<IWebMutableURLRequest> request;
+ if (FAILED(dataSource->request(&request)) || !request)
+ return E_FAIL;
+
+ if (FAILED(request->URL(urlString)))
+ return E_FAIL;
+
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE WebView::mainFrameDocument(
@@ -3569,6 +3687,15 @@ HRESULT STDMETHODCALLTYPE WebView::toggleGrammarChecking(
return setGrammarCheckingEnabled(enabled ? FALSE : TRUE);
}
+HRESULT STDMETHODCALLTYPE WebView::reloadFromOrigin(
+ /* [in] */ IUnknown* /*sender*/)
+{
+ if (!m_mainFrame)
+ return E_FAIL;
+
+ return m_mainFrame->reloadFromOrigin();
+}
+
// IWebViewCSS -----------------------------------------------------------------
HRESULT STDMETHODCALLTYPE WebView::computedStyleForElement(
@@ -4339,6 +4466,11 @@ HRESULT WebView::notifyPreferencesChanged(IWebNotification* notification)
return hr;
settings->setLocalStorageEnabled(enabled);
+ hr = prefsPrivate->experimentalNotificationsEnabled(&enabled);
+ if (FAILED(hr))
+ return hr;
+ settings->setExperimentalNotificationsEnabled(enabled);
+
hr = prefsPrivate->isWebSecurityEnabled(&enabled);
if (FAILED(hr))
return hr;
@@ -4361,6 +4493,21 @@ HRESULT WebView::notifyPreferencesChanged(IWebNotification* notification)
settings->setShouldPaintNativeControls(!!enabled);
#endif
+ hr = prefsPrivate->shouldUseHighResolutionTimers(&enabled);
+ if (FAILED(hr))
+ return hr;
+ settings->setShouldUseHighResolutionTimers(enabled);
+
+ UINT runTime;
+ hr = prefsPrivate->pluginAllowedRunTime(&runTime);
+ if (FAILED(hr))
+ return hr;
+ settings->setPluginAllowedRunTime(runTime);
+
+#if ENABLE(3D_CANVAS)
+ settings->setExperimentalWebGLEnabled(true);
+#endif // ENABLE(3D_CANVAS)
+
if (!m_closeWindowTimer.isActive())
m_mainFrame->invalidate(); // FIXME
@@ -4392,6 +4539,20 @@ HRESULT updateSharedSettingsFromPreferencesIfNeeded(IWebPreferences* preferences
// IWebViewPrivate ------------------------------------------------------------
+HRESULT STDMETHODCALLTYPE WebView::MIMETypeForExtension(
+ /* [in] */ BSTR extension,
+ /* [retval][out] */ BSTR* mimeType)
+{
+ if (!mimeType)
+ return E_POINTER;
+
+ String extensionStr(extension, SysStringLen(extension));
+
+ *mimeType = BString(MIMETypeRegistry::getMIMETypeForExtension(extensionStr)).release();
+
+ return S_OK;
+}
+
HRESULT STDMETHODCALLTYPE WebView::setCustomDropTarget(
/* [in] */ IDropTarget* dt)
{
@@ -4515,11 +4676,25 @@ static DWORD dragOperationToDragCursor(DragOperation op) {
return res;
}
-static DragOperation keyStateToDragOperation(DWORD) {
- //FIXME: This is currently very simple, it may need to actually
- //work out an appropriate DragOperation in future -- however this
- //behaviour appears to match FireFox
- return (DragOperation)(DragOperationCopy | DragOperationLink);
+DragOperation WebView::keyStateToDragOperation(DWORD grfKeyState) const
+{
+ if (!m_page)
+ return DragOperationNone;
+
+ // Conforms to Microsoft's key combinations as documented for
+ // IDropTarget::DragOver. Note, grfKeyState is the current
+ // state of the keyboard modifier keys on the keyboard. See:
+ // <http://msdn.microsoft.com/en-us/library/ms680129(VS.85).aspx>.
+ DragOperation operation = m_page->dragController()->sourceDragOperation();
+
+ if ((grfKeyState & (MK_CONTROL | MK_SHIFT)) == (MK_CONTROL | MK_SHIFT))
+ operation = DragOperationLink;
+ else if ((grfKeyState & MK_CONTROL) == MK_CONTROL)
+ operation = DragOperationCopy;
+ else if ((grfKeyState & MK_SHIFT) == MK_SHIFT)
+ operation = DragOperationGeneric;
+
+ return operation;
}
HRESULT STDMETHODCALLTYPE WebView::DragEnter(
@@ -4536,6 +4711,7 @@ HRESULT STDMETHODCALLTYPE WebView::DragEnter(
IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
*pdwEffect = dragOperationToDragCursor(m_page->dragController()->dragEntered(&data));
+ m_lastDropEffect = *pdwEffect;
m_dragData = pDataObject;
return S_OK;
@@ -4556,6 +4732,7 @@ HRESULT STDMETHODCALLTYPE WebView::DragOver(
} else
*pdwEffect = DROPEFFECT_NONE;
+ m_lastDropEffect = *pdwEffect;
return S_OK;
}
@@ -4580,7 +4757,7 @@ HRESULT STDMETHODCALLTYPE WebView::Drop(
m_dropTargetHelper->Drop(pDataObject, (POINT*)&pt, *pdwEffect);
m_dragData = 0;
- *pdwEffect = DROPEFFECT_NONE;
+ *pdwEffect = m_lastDropEffect;
POINTL localpt = pt;
::ScreenToClient(m_viewWindow, (LPPOINT)&localpt);
DragData data(pDataObject, IntPoint(localpt.x, localpt.y),
@@ -4706,7 +4883,7 @@ HRESULT STDMETHODCALLTYPE WebView::loadBackForwardListFromOtherView(
// If this item is showing , save away its current scroll and form state,
// since that might have changed since loading and it is normally not saved
// until we leave that page.
- otherWebView->m_page->mainFrame()->loader()->saveDocumentAndScrollState();
+ otherWebView->m_page->mainFrame()->loader()->history()->saveDocumentAndScrollState();
}
RefPtr<HistoryItem> newItem = otherBackForwardList->itemAtIndex(i)->copy();
if (!i)
@@ -5324,6 +5501,226 @@ HRESULT WebView::setCanStartPlugins(BOOL canStartPlugins)
return S_OK;
}
+static String toString(BSTR bstr)
+{
+ return String(bstr, SysStringLen(bstr));
+}
+
+static KURL toKURL(BSTR bstr)
+{
+ return KURL(KURL(), toString(bstr));
+}
+
+static PassOwnPtr<Vector<String> > toStringVector(unsigned patternsCount, BSTR* patterns)
+{
+ // Convert the patterns into a Vector.
+ if (patternsCount == 0)
+ return 0;
+ Vector<String>* patternsVector = new Vector<String>;
+ for (unsigned i = 0; i < patternsCount; ++i)
+ patternsVector->append(toString(patterns[i]));
+ return patternsVector;
+}
+
+HRESULT WebView::addUserScriptToGroup(BSTR groupName, IWebScriptWorld* iWorld, BSTR source, BSTR url,
+ unsigned whitelistCount, BSTR* whitelist,
+ unsigned blacklistCount, BSTR* blacklist,
+ WebUserScriptInjectionTime injectionTime)
+{
+ COMPtr<WebScriptWorld> world(Query, iWorld);
+ if (!world)
+ return E_POINTER;
+
+ String group = toString(groupName);
+ if (group.isEmpty())
+ return E_INVALIDARG;
+
+ PageGroup* pageGroup = PageGroup::pageGroup(group);
+ ASSERT(pageGroup);
+ if (!pageGroup)
+ return E_FAIL;
+
+ pageGroup->addUserScriptToWorld(world->world(), toString(source), toKURL(url),
+ toStringVector(whitelistCount, whitelist), toStringVector(blacklistCount, blacklist),
+ injectionTime == WebInjectAtDocumentStart ? InjectAtDocumentStart : InjectAtDocumentEnd);
+
+ return S_OK;
+}
+
+HRESULT WebView::addUserStyleSheetToGroup(BSTR groupName, IWebScriptWorld* iWorld, BSTR source, BSTR url,
+ unsigned whitelistCount, BSTR* whitelist,
+ unsigned blacklistCount, BSTR* blacklist)
+{
+ COMPtr<WebScriptWorld> world(Query, iWorld);
+ if (!world)
+ return E_POINTER;
+
+ String group = toString(groupName);
+ if (group.isEmpty())
+ return E_INVALIDARG;
+
+ PageGroup* pageGroup = PageGroup::pageGroup(group);
+ ASSERT(pageGroup);
+ if (!pageGroup)
+ return E_FAIL;
+
+ pageGroup->addUserStyleSheetToWorld(world->world(), toString(source), toKURL(url),
+ toStringVector(whitelistCount, whitelist), toStringVector(blacklistCount, blacklist));
+
+ return S_OK;
+}
+
+HRESULT WebView::removeUserScriptFromGroup(BSTR groupName, IWebScriptWorld* iWorld, BSTR url)
+{
+ COMPtr<WebScriptWorld> world(Query, iWorld);
+ if (!world)
+ return E_POINTER;
+
+ String group = toString(groupName);
+ if (group.isEmpty())
+ return E_INVALIDARG;
+
+ PageGroup* pageGroup = PageGroup::pageGroup(group);
+ ASSERT(pageGroup);
+ if (!pageGroup)
+ return E_FAIL;
+
+ pageGroup->removeUserScriptFromWorld(world->world(), toKURL(url));
+
+ return S_OK;
+}
+
+HRESULT WebView::removeUserStyleSheetFromGroup(BSTR groupName, IWebScriptWorld* iWorld, BSTR url)
+{
+ COMPtr<WebScriptWorld> world(Query, iWorld);
+ if (!world)
+ return E_POINTER;
+
+ String group = toString(groupName);
+ if (group.isEmpty())
+ return E_INVALIDARG;
+
+ PageGroup* pageGroup = PageGroup::pageGroup(group);
+ ASSERT(pageGroup);
+ if (!pageGroup)
+ return E_FAIL;
+
+ pageGroup->removeUserStyleSheetFromWorld(world->world(), toKURL(url));
+
+ return S_OK;
+}
+
+HRESULT WebView::removeUserScriptsFromGroup(BSTR groupName, IWebScriptWorld* iWorld)
+{
+ COMPtr<WebScriptWorld> world(Query, iWorld);
+ if (!world)
+ return E_POINTER;
+
+ String group = toString(groupName);
+ if (group.isEmpty())
+ return E_INVALIDARG;
+
+ PageGroup* pageGroup = PageGroup::pageGroup(group);
+ ASSERT(pageGroup);
+ if (!pageGroup)
+ return E_FAIL;
+
+ pageGroup->removeUserScriptsFromWorld(world->world());
+ return S_OK;
+}
+
+HRESULT WebView::removeUserStyleSheetsFromGroup(BSTR groupName, IWebScriptWorld* iWorld)
+{
+ COMPtr<WebScriptWorld> world(Query, iWorld);
+ if (!world)
+ return E_POINTER;
+
+ String group = toString(groupName);
+ if (group.isEmpty())
+ return E_INVALIDARG;
+
+ PageGroup* pageGroup = PageGroup::pageGroup(group);
+ ASSERT(pageGroup);
+ if (!pageGroup)
+ return E_FAIL;
+
+ pageGroup->removeUserStyleSheetsFromWorld(world->world());
+ return S_OK;
+}
+
+HRESULT WebView::removeAllUserContentFromGroup(BSTR groupName)
+{
+ String group = toString(groupName);
+ if (group.isEmpty())
+ return E_INVALIDARG;
+
+ PageGroup* pageGroup = PageGroup::pageGroup(group);
+ ASSERT(pageGroup);
+ if (!pageGroup)
+ return E_FAIL;
+
+ pageGroup->removeAllUserContent();
+ return S_OK;
+}
+
+HRESULT WebView::invalidateBackingStore(const RECT* rect)
+{
+ if (!IsWindow(m_viewWindow))
+ return S_OK;
+
+ RECT clientRect;
+ if (!GetClientRect(m_viewWindow, &clientRect))
+ return E_FAIL;
+
+ RECT rectToInvalidate;
+ if (!rect)
+ rectToInvalidate = clientRect;
+ else if (!IntersectRect(&rectToInvalidate, &clientRect, rect))
+ return S_OK;
+
+ repaint(rectToInvalidate, true);
+ return S_OK;
+}
+
+HRESULT WebView::whiteListAccessFromOrigin(BSTR sourceOrigin, BSTR destinationProtocol, BSTR destinationHost, BOOL allowDestinationSubdomains)
+{
+ SecurityOrigin::whiteListAccessFromOrigin(*SecurityOrigin::createFromString(String(sourceOrigin, SysStringLen(sourceOrigin))), String(destinationProtocol, SysStringLen(destinationProtocol)), String(destinationHost, SysStringLen(destinationHost)), allowDestinationSubdomains);
+ return S_OK;
+}
+
+HRESULT WebView::resetOriginAccessWhiteLists()
+{
+ SecurityOrigin::resetOriginAccessWhiteLists();
+ return S_OK;
+}
+
+HRESULT WebView::setHistoryDelegate(IWebHistoryDelegate* historyDelegate)
+{
+ m_historyDelegate = historyDelegate;
+ return S_OK;
+}
+
+HRESULT WebView::historyDelegate(IWebHistoryDelegate** historyDelegate)
+{
+ if (!historyDelegate)
+ return E_POINTER;
+
+ return m_historyDelegate.copyRefTo(historyDelegate);
+}
+
+HRESULT WebView::addVisitedLinks(BSTR* visitedURLs, unsigned visitedURLCount)
+{
+ PageGroup& group = core(this)->group();
+
+ for (unsigned i = 0; i < visitedURLCount; ++i) {
+ BSTR url = visitedURLs[i];
+ unsigned length = SysStringLen(url);
+ group.addVisitedLink(url, length);
+ }
+
+ return S_OK;
+}
+
void WebView::downloadURL(const KURL& url)
{
// It's the delegate's job to ref the WebDownload to keep it alive - otherwise it will be
@@ -5332,6 +5729,152 @@ void WebView::downloadURL(const KURL& url)
download->start();
}
+#if USE(ACCELERATED_COMPOSITING)
+void WebView::setRootChildLayer(WebCore::PlatformLayer* layer)
+{
+ setAcceleratedCompositing(layer ? true : false);
+ if (m_layerRenderer)
+ m_layerRenderer->setRootChildLayer(layer);
+}
+
+void WebView::setAcceleratedCompositing(bool accelerated)
+{
+ if (m_isAcceleratedCompositing == accelerated || !WKCACFLayerRenderer::acceleratedCompositingAvailable())
+ return;
+
+ if (accelerated) {
+ m_layerRenderer = WKCACFLayerRenderer::create();
+ if (m_layerRenderer) {
+ m_isAcceleratedCompositing = true;
+
+ // Create the root layer
+ ASSERT(m_viewWindow);
+ m_layerRenderer->setHostWindow(m_viewWindow);
+ updateRootLayerContents();
+ }
+ } else {
+ m_layerRenderer = 0;
+ m_isAcceleratedCompositing = false;
+ }
+}
+
+void WebView::updateRootLayerContents()
+{
+ if (!m_backingStoreBitmap || !m_layerRenderer)
+ return;
+
+ // Get the backing store into a CGImage
+ BITMAP bitmap;
+ GetObject(m_backingStoreBitmap.get(), sizeof(bitmap), &bitmap);
+ int bmSize = bitmap.bmWidthBytes * bitmap.bmHeight;
+ RetainPtr<CFDataRef> data(AdoptCF,
+ CFDataCreateWithBytesNoCopy(
+ 0, static_cast<UInt8*>(bitmap.bmBits),
+ bmSize, kCFAllocatorNull));
+ RetainPtr<CGDataProviderRef> cgData(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
+ RetainPtr<CGColorSpaceRef> space(AdoptCF, CGColorSpaceCreateDeviceRGB());
+ RetainPtr<CGImageRef> backingStoreImage(AdoptCF, CGImageCreate(bitmap.bmWidth, bitmap.bmHeight,
+ 8, bitmap.bmBitsPixel,
+ bitmap.bmWidthBytes, space.get(),
+ kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst,
+ cgData.get(), 0, false,
+ kCGRenderingIntentDefault));
+
+ // Hand the CGImage to CACF for compositing
+ m_layerRenderer->setRootContents(backingStoreImage.get());
+
+ // Set the frame and scroll position
+ Frame* coreFrame = core(m_mainFrame);
+ if (!coreFrame)
+ return;
+ FrameView* frameView = coreFrame->view();
+
+ m_layerRenderer->setScrollFrame(frameView->layoutWidth(), frameView->layoutHeight(),
+ frameView->scrollX(), frameView->scrollY());
+}
+#endif
+
+HRESULT STDMETHODCALLTYPE WebView::setPluginHalterDelegate(IWebPluginHalterDelegate* d)
+{
+ m_pluginHalterDelegate = d;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE WebView::pluginHalterDelegate(IWebPluginHalterDelegate** d)
+{
+ if (!d)
+ return E_POINTER;
+
+ if (!m_pluginHalterDelegate)
+ return E_FAIL;
+
+ return m_pluginHalterDelegate.copyRefTo(d);
+}
+
+static PluginView* pluginViewForNode(IDOMNode* domNode)
+{
+ COMPtr<DOMNode> webKitDOMNode(Query, domNode);
+ if (!webKitDOMNode)
+ return 0;
+
+ Node* node = webKitDOMNode->node();
+ if (!node)
+ return 0;
+
+ RenderObject* renderer = node->renderer();
+ if (!renderer || !renderer->isWidget())
+ return 0;
+
+ Widget* widget = toRenderWidget(renderer)->widget();
+ if (!widget || !widget->isPluginView())
+ return 0;
+
+ return static_cast<PluginView*>(widget);
+}
+
+HRESULT WebView::isNodeHaltedPlugin(IDOMNode* domNode, BOOL* result)
+{
+ if (!domNode || !result)
+ return E_POINTER;
+
+ *result = FALSE;
+
+ PluginView* view = pluginViewForNode(domNode);
+ if (!view)
+ return E_FAIL;
+
+ *result = view->isHalted();
+ return S_OK;
+}
+
+HRESULT WebView::restartHaltedPluginForNode(IDOMNode* domNode)
+{
+ if (!domNode)
+ return E_POINTER;
+
+ PluginView* view = pluginViewForNode(domNode);
+ if (!view)
+ return E_FAIL;
+
+ view->restart();
+ return S_OK;
+}
+
+HRESULT WebView::hasPluginForNodeBeenHalted(IDOMNode* domNode, BOOL* result)
+{
+ if (!domNode || !result)
+ return E_POINTER;
+
+ *result = FALSE;
+
+ PluginView* view = pluginViewForNode(domNode);
+ if (!view)
+ return E_FAIL;
+
+ *result = view->hasBeenHalted();
+ return S_OK;
+}
+
class EnumTextMatches : public IEnumTextMatches
{
long m_ref;
@@ -5415,4 +5958,3 @@ Page* core(IWebView* iWebView)
return page;
}
-