WinLauncher fails to download files.
[WebKit-https.git] / Source / WebKit / win / WebView.cpp
index dbe1524..80946fe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2013 Apple, Inc.  All rights reserved.
+ * Copyright (C) 2006-2015 Apple, Inc.  All rights reserved.
  * Copyright (C) 2009, 2010, 2011 Appcelerator, Inc. All rights reserved.
  * Copyright (C) 2011 Brent Fulgham. All rights reserved.
  *
  *    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 COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. 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
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#include "config.h"
 #include "WebView.h"
 
+#include "BackForwardController.h"
 #include "COMVariantSetter.h"
 #include "DOMCoreClasses.h"
 #include "FullscreenVideoController.h"
 #include "MarshallingHelpers.h"
+#include "PluginDatabase.h"
+#include "PluginView.h"
+#include "ResourceLoadScheduler.h"
 #include "SoftLinking.h"
 #include "SubframeLoader.h"
 #include "TextIterator.h"
@@ -40,6 +43,7 @@
 #include "WebContextMenuClient.h"
 #include "WebCoreTextRenderer.h"
 #include "WebDatabaseManager.h"
+#include "WebDatabaseProvider.h"
 #include "WebDocumentLoader.h"
 #include "WebDownload.h"
 #include "WebDragClient.h"
 #include "WebPlatformStrategies.h"
 #include "WebPreferences.h"
 #include "WebScriptWorld.h"
+#include "WebStorageNamespaceProvider.h"
+#include "WebViewGroup.h"
+#include "WebVisitedLinkStore.h"
 #include "resource.h"
 #include <JavaScriptCore/APICast.h>
+#include <JavaScriptCore/Exception.h>
 #include <JavaScriptCore/InitializeThreading.h>
 #include <JavaScriptCore/JSCJSValue.h>
 #include <JavaScriptCore/JSLock.h>
+#include <JavaScriptCore/Profile.h>
 #include <WebCore/AXObjectCache.h>
 #include <WebCore/ApplicationCacheStorage.h>
 #include <WebCore/BString.h>
+#include <WebCore/BackForwardController.h>
 #include <WebCore/BackForwardList.h>
 #include <WebCore/BitmapInfo.h>
 #include <WebCore/Chrome.h>
 #include <WebCore/DocumentMarkerController.h>
 #include <WebCore/DragController.h>
 #include <WebCore/DragData.h>
-#include <WebCore/DragSession.h>
 #include <WebCore/Editor.h>
 #include <WebCore/EventHandler.h>
 #include <WebCore/EventNames.h>
 #include <WebCore/FileSystem.h>
 #include <WebCore/FloatQuad.h>
 #include <WebCore/FocusController.h>
+#include <WebCore/Font.h>
 #include <WebCore/FrameLoader.h>
 #include <WebCore/FrameSelection.h>
 #include <WebCore/FrameTree.h>
 #include <WebCore/FrameView.h>
 #include <WebCore/FrameWin.h>
+#include <WebCore/FullScreenController.h>
 #include <WebCore/GDIObjectCounter.h>
 #include <WebCore/GeolocationController.h>
 #include <WebCore/GeolocationError.h>
 #include <WebCore/GraphicsContext.h>
-#include <WebCore/HTMLMediaElement.h>
 #include <WebCore/HTMLNames.h>
+#include <WebCore/HTMLVideoElement.h>
 #include <WebCore/HWndDC.h>
 #include <WebCore/HistoryController.h>
 #include <WebCore/HistoryItem.h>
 #include <WebCore/NotImplemented.h>
 #include <WebCore/Page.h>
 #include <WebCore/PageCache.h>
+#include <WebCore/PageConfiguration.h>
 #include <WebCore/PageGroup.h>
 #include <WebCore/PlatformKeyboardEvent.h>
 #include <WebCore/PlatformMouseEvent.h>
 #include <WebCore/PlatformWheelEvent.h>
 #include <WebCore/PluginData.h>
-#include <WebCore/PluginDatabase.h>
-#include <WebCore/PluginView.h>
 #include <WebCore/PopupMenu.h>
 #include <WebCore/PopupMenuWin.h>
 #include <WebCore/ProgressTracker.h>
 #include <WebCore/SecurityOrigin.h>
 #include <WebCore/SecurityPolicy.h>
 #include <WebCore/Settings.h>
-#include <WebCore/SimpleFontData.h>
 #include <WebCore/SystemInfo.h>
+#include <WebCore/UserContentController.h>
 #include <WebCore/WindowMessageBroadcaster.h>
 #include <WebCore/WindowsTouch.h>
 #include <bindings/ScriptValue.h>
 #include <wtf/MainThread.h>
+#include <wtf/RAMSize.h>
 
 #if USE(CG)
 #include <CoreGraphics/CGContext.h>
 #if USE(CFNETWORK)
 #include <CFNetwork/CFURLCachePriv.h>
 #include <CFNetwork/CFURLProtocolPriv.h>
-#include <WebKitSystemInterface/WebKitSystemInterface.h> 
+#include <WebKitSystemInterface/WebKitSystemInterface.h>
+#elif USE(CURL)
+#include <WebCore/CurlCacheManager.h>
 #endif
 
-#if USE(ACCELERATED_COMPOSITING) && USE(CA)
+#if USE(CA)
 #include <WebCore/CACFLayerTreeHost.h>
 #include <WebCore/PlatformCALayer.h>
+#elif USE(TEXTURE_MAPPER_GL)
+#include "AcceleratedCompositingContext.h"
 #endif
 
 #if ENABLE(FULLSCREEN_API)
@@ -198,7 +213,11 @@ using namespace std;
 using JSC::JSLock;
 
 static HMODULE accessibilityLib;
-static HashSet<WebView*> pendingDeleteBackingStoreSet;
+static HashSet<WebView*>& pendingDeleteBackingStoreSet()
+{
+    static NeverDestroyed<HashSet<WebView*>> pendingDeleteBackingStoreSet;
+    return pendingDeleteBackingStoreSet;
+}
 
 static CFStringRef WebKitLocalCacheDefaultsKey = CFSTR("WebKitLocalCache");
 
@@ -225,11 +244,25 @@ static inline String toString(BSTR bstr)
     return String(bstr, SysStringLen(bstr));
 }
 
+static inline String toString(BString &bstr)
+{
+    return String(bstr, SysStringLen(bstr));
+}
+
 static inline URL toURL(BSTR bstr)
 {
     return URL(URL(), toString(bstr));
 }
 
+static String localStorageDatabasePath(WebPreferences* preferences)
+{
+    BString localStorageDatabasePath;
+    if (FAILED(preferences->localStorageDatabasePath(&localStorageDatabasePath)))
+        return String();
+
+    return toString(localStorageDatabasePath);
+}
+
 class PreferencesChangedOrRemovedObserver : public IWebNotificationObserver {
 public:
     static PreferencesChangedOrRemovedObserver* sharedInstance();
@@ -366,9 +399,7 @@ WebView::WebView()
     , m_viewWindow(0)
     , m_mainFrame(0)
     , m_page(0)
-#if ENABLE(INSPECTOR)
     , m_inspectorClient(0)
-#endif // ENABLE(INSPECTOR)
     , m_hasCustomDropTarget(false)
     , m_useBackForwardList(true)
     , m_userAgentOverridden(false)
@@ -391,13 +422,14 @@ WebView::WebView()
     , m_lastPanY(0)
     , m_xOverpan(0)
     , m_yOverpan(0)
-#if USE(ACCELERATED_COMPOSITING)
     , m_isAcceleratedCompositing(false)
-#endif
     , m_nextDisplayIsSynchronous(false)
     , m_lastSetCursor(0)
     , m_usesLayeredWindow(false)
     , m_needsDisplay(false)
+#if USE(TEXTURE_MAPPER_GL)
+    , m_acceleratedCompositingContext(nullptr)
+#endif
 {
     JSC::initializeThreading();
     WTF::initializeMainThread();
@@ -415,9 +447,12 @@ WebView::WebView()
     if (SUCCEEDED(sharedPreferences->grammarCheckingEnabled(&enabled)))
         grammarCheckingEnabled = !!enabled;
 
+    m_webViewGroup = WebViewGroup::getOrCreate(String(), localStorageDatabasePath(sharedPreferences));
+    m_webViewGroup->addWebView(this);
+
     WebViewCount++;
     gClassCount++;
-    gClassNameCount.add("WebView");
+    gClassNameCount().add("WebView");
 }
 
 WebView::~WebView()
@@ -432,16 +467,15 @@ WebView::~WebView()
     ASSERT(!m_preferences);
     ASSERT(!m_viewWindow);
 
-#if USE(ACCELERATED_COMPOSITING)
 #if USE(CA)
     ASSERT(!m_layerTreeHost);
 #endif
-    ASSERT(!m_backingLayer);
-#endif
+
+    m_webViewGroup->removeWebView(this);
 
     WebViewCount--;
     gClassCount--;
-    gClassNameCount.remove("WebView");
+    gClassNameCount().remove("WebView");
 }
 
 WebView* WebView::createInstance()
@@ -481,10 +515,12 @@ void WebView::removeFromAllWebViewsSet()
 
 void WebView::setCacheModel(WebCacheModel cacheModel)
 {
-#if USE(CFNETWORK)
     if (s_didSetCacheModel && cacheModel == s_cacheModel)
         return;
 
+    String cacheDirectory;
+
+#if USE(CFNETWORK)
     RetainPtr<CFURLCacheRef> cfurlCache = adoptCF(CFURLCacheCopySharedURLCache());
     RetainPtr<CFStringRef> cfurlCacheDirectory = adoptCF(wkCopyFoundationCacheDirectory(0));
     if (!cfurlCacheDirectory) {
@@ -494,26 +530,33 @@ void WebView::setCacheModel(WebCacheModel cacheModel)
         else
             cfurlCacheDirectory = WebCore::localUserSpecificStorageDirectory().createCFString();
     }
+    cacheDirectory = String(cfurlCacheDirectory);
+    CFIndex cacheMemoryCapacity = 0;
+    CFIndex cacheDiskCapacity = 0;
+#elif USE(CURL)
+    cacheDirectory = CurlCacheManager::getInstance().cacheDirectory();
+    long cacheMemoryCapacity = 0;
+    long cacheDiskCapacity = 0;
+#endif
+
+    unsigned long long memSize = ramSize() / 1024 / 1024;
 
     // As a fudge factor, use 1000 instead of 1024, in case the reported byte 
     // count doesn't align exactly to a megabyte boundary.
-    unsigned long long memSize = WebMemorySize() / 1024 / 1000;
-    unsigned long long diskFreeSize = WebVolumeFreeSize(cfurlCacheDirectory.get()) / 1024 / 1000;
+    unsigned long long diskFreeSize = WebVolumeFreeSize(cacheDirectory) / 1024 / 1000;
 
     unsigned cacheTotalCapacity = 0;
     unsigned cacheMinDeadCapacity = 0;
     unsigned cacheMaxDeadCapacity = 0;
-    double deadDecodedDataDeletionInterval = 0;
+    auto deadDecodedDataDeletionInterval = std::chrono::seconds { 0 };
 
-    unsigned pageCacheCapacity = 0;
+    unsigned pageCacheSize = 0;
 
-    CFIndex cfurlCacheMemoryCapacity = 0;
-    CFIndex cfurlCacheDiskCapacity = 0;
 
     switch (cacheModel) {
     case WebCacheModelDocumentViewer: {
         // Page cache capacity (in pages)
-        pageCacheCapacity = 0;
+        pageCacheSize = 0;
 
         // Object cache capacities (in bytes)
         if (memSize >= 2048)
@@ -528,24 +571,25 @@ void WebView::setCacheModel(WebCacheModel cacheModel)
         cacheMinDeadCapacity = 0;
         cacheMaxDeadCapacity = 0;
 
-        // Foundation memory cache capacity (in bytes)
-        cfurlCacheMemoryCapacity = 0;
+        // Memory cache capacity (in bytes)
+        cacheMemoryCapacity = 0;
 
+#if USE(CFNETWORK)
         // Foundation disk cache capacity (in bytes)
-        cfurlCacheDiskCapacity = CFURLCacheDiskCapacity(cfurlCache.get());
-
+        cacheDiskCapacity = CFURLCacheDiskCapacity(cfurlCache.get());
+#endif
         break;
     }
     case WebCacheModelDocumentBrowser: {
         // Page cache capacity (in pages)
         if (memSize >= 1024)
-            pageCacheCapacity = 3;
+            pageCacheSize = 3;
         else if (memSize >= 512)
-            pageCacheCapacity = 2;
+            pageCacheSize = 2;
         else if (memSize >= 256)
-            pageCacheCapacity = 1;
+            pageCacheSize = 1;
         else
-            pageCacheCapacity = 0;
+            pageCacheSize = 0;
 
         // Object cache capacities (in bytes)
         if (memSize >= 2048)
@@ -560,25 +604,25 @@ void WebView::setCacheModel(WebCacheModel cacheModel)
         cacheMinDeadCapacity = cacheTotalCapacity / 8;
         cacheMaxDeadCapacity = cacheTotalCapacity / 4;
 
-        // Foundation memory cache capacity (in bytes)
+        // Memory cache capacity (in bytes)
         if (memSize >= 2048)
-            cfurlCacheMemoryCapacity = 4 * 1024 * 1024;
+            cacheMemoryCapacity = 4 * 1024 * 1024;
         else if (memSize >= 1024)
-            cfurlCacheMemoryCapacity = 2 * 1024 * 1024;
+            cacheMemoryCapacity = 2 * 1024 * 1024;
         else if (memSize >= 512)
-            cfurlCacheMemoryCapacity = 1 * 1024 * 1024;
+            cacheMemoryCapacity = 1 * 1024 * 1024;
         else
-            cfurlCacheMemoryCapacity =      512 * 1024; 
+            cacheMemoryCapacity =      512 * 1024; 
 
-        // Foundation disk cache capacity (in bytes)
+        // Disk cache capacity (in bytes)
         if (diskFreeSize >= 16384)
-            cfurlCacheDiskCapacity = 50 * 1024 * 1024;
+            cacheDiskCapacity = 50 * 1024 * 1024;
         else if (diskFreeSize >= 8192)
-            cfurlCacheDiskCapacity = 40 * 1024 * 1024;
+            cacheDiskCapacity = 40 * 1024 * 1024;
         else if (diskFreeSize >= 4096)
-            cfurlCacheDiskCapacity = 30 * 1024 * 1024;
+            cacheDiskCapacity = 30 * 1024 * 1024;
         else
-            cfurlCacheDiskCapacity = 20 * 1024 * 1024;
+            cacheDiskCapacity = 20 * 1024 * 1024;
 
         break;
     }
@@ -586,15 +630,15 @@ void WebView::setCacheModel(WebCacheModel cacheModel)
         // Page cache capacity (in pages)
         // (Research indicates that value / page drops substantially after 3 pages.)
         if (memSize >= 2048)
-            pageCacheCapacity = 5;
+            pageCacheSize = 5;
         else if (memSize >= 1024)
-            pageCacheCapacity = 4;
+            pageCacheSize = 4;
         else if (memSize >= 512)
-            pageCacheCapacity = 3;
+            pageCacheSize = 3;
         else if (memSize >= 256)
-            pageCacheCapacity = 2;
+            pageCacheSize = 2;
         else
-            pageCacheCapacity = 1;
+            pageCacheSize = 1;
 
         // Object cache capacities (in bytes)
         // (Testing indicates that value / MB depends heavily on content and
@@ -616,32 +660,32 @@ void WebView::setCacheModel(WebCacheModel cacheModel)
         // can prove that the overall system gain would justify the regression.
         cacheMaxDeadCapacity = max(24u, cacheMaxDeadCapacity);
 
-        deadDecodedDataDeletionInterval = 60;
+        deadDecodedDataDeletionInterval = std::chrono::seconds { 60 };
 
-        // Foundation memory cache capacity (in bytes)
+        // Memory cache capacity (in bytes)
         // (These values are small because WebCore does most caching itself.)
         if (memSize >= 1024)
-            cfurlCacheMemoryCapacity = 4 * 1024 * 1024;
+            cacheMemoryCapacity = 4 * 1024 * 1024;
         else if (memSize >= 512)
-            cfurlCacheMemoryCapacity = 2 * 1024 * 1024;
+            cacheMemoryCapacity = 2 * 1024 * 1024;
         else if (memSize >= 256)
-            cfurlCacheMemoryCapacity = 1 * 1024 * 1024;
+            cacheMemoryCapacity = 1 * 1024 * 1024;
         else
-            cfurlCacheMemoryCapacity =      512 * 1024; 
+            cacheMemoryCapacity =      512 * 1024; 
 
-        // Foundation disk cache capacity (in bytes)
+        // Disk cache capacity (in bytes)
         if (diskFreeSize >= 16384)
-            cfurlCacheDiskCapacity = 175 * 1024 * 1024;
+            cacheDiskCapacity = 175 * 1024 * 1024;
         else if (diskFreeSize >= 8192)
-            cfurlCacheDiskCapacity = 150 * 1024 * 1024;
+            cacheDiskCapacity = 150 * 1024 * 1024;
         else if (diskFreeSize >= 4096)
-            cfurlCacheDiskCapacity = 125 * 1024 * 1024;
+            cacheDiskCapacity = 125 * 1024 * 1024;
         else if (diskFreeSize >= 2048)
-            cfurlCacheDiskCapacity = 100 * 1024 * 1024;
+            cacheDiskCapacity = 100 * 1024 * 1024;
         else if (diskFreeSize >= 1024)
-            cfurlCacheDiskCapacity = 75 * 1024 * 1024;
+            cacheDiskCapacity = 75 * 1024 * 1024;
         else
-            cfurlCacheDiskCapacity = 50 * 1024 * 1024;
+            cacheDiskCapacity = 50 * 1024 * 1024;
 
         break;
     }
@@ -649,20 +693,24 @@ void WebView::setCacheModel(WebCacheModel cacheModel)
         ASSERT_NOT_REACHED();
     }
 
-    // Don't shrink a big disk cache, since that would cause churn.
-    cfurlCacheDiskCapacity = max(cfurlCacheDiskCapacity, CFURLCacheDiskCapacity(cfurlCache.get()));
+    auto& memoryCache = MemoryCache::singleton();
+    memoryCache.setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity);
+    memoryCache.setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval);
+    PageCache::singleton().setMaxSize(pageCacheSize);
 
-    memoryCache()->setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity);
-    memoryCache()->setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval);
-    pageCache()->setCapacity(pageCacheCapacity);
+#if USE(CFNETWORK)
+    // Don't shrink a big disk cache, since that would cause churn.
+    cacheDiskCapacity = max(cacheDiskCapacity, CFURLCacheDiskCapacity(cfurlCache.get()));
 
-    CFURLCacheSetMemoryCapacity(cfurlCache.get(), cfurlCacheMemoryCapacity);
-    CFURLCacheSetDiskCapacity(cfurlCache.get(), cfurlCacheDiskCapacity);
+    CFURLCacheSetMemoryCapacity(cfurlCache.get(), cacheMemoryCapacity);
+    CFURLCacheSetDiskCapacity(cfurlCache.get(), cacheDiskCapacity);
+#elif USE(CURL)
+    CurlCacheManager::getInstance().setStorageSizeLimit(cacheDiskCapacity);
+#endif
 
     s_didSetCacheModel = true;
     s_cacheModel = cacheModel;
     return;
-#endif
 }
 
 WebCacheModel WebView::cacheModel()
@@ -701,9 +749,7 @@ 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);
 
@@ -718,7 +764,7 @@ HRESULT STDMETHODCALLTYPE WebView::close()
     if (m_mouseOutTracker) {
         m_mouseOutTracker->dwFlags = TME_CANCEL;
         ::TrackMouseEvent(m_mouseOutTracker.get());
-        m_mouseOutTracker.clear();
+        m_mouseOutTracker.reset();
     }
     
     revokeDragDrop();
@@ -746,11 +792,9 @@ HRESULT STDMETHODCALLTYPE WebView::close()
     setUIDelegate(0);
     setFormDelegate(0);
 
-#if ENABLE(INSPECTOR)
     m_inspectorClient = 0;
     if (m_webInspector)
         m_webInspector->webViewClosed();
-#endif // ENABLE(INSPECTOR)
 
     delete m_page;
     m_page = 0;
@@ -777,14 +821,12 @@ HRESULT STDMETHODCALLTYPE WebView::close()
 
 void WebView::repaint(const WebCore::IntRect& windowRect, bool contentChanged, bool immediate, bool repaintContentOnly)
 {
-#if USE(ACCELERATED_COMPOSITING)
     if (isAcceleratedCompositing()) {
         // The contentChanged, immediate, and repaintContentOnly parameters are all based on a non-
         // compositing painting/scrolling model.
         addToDirtyRegion(windowRect);
         return;
     }
-#endif
 
     if (!repaintContentOnly) {
         RECT rect = windowRect;
@@ -803,7 +845,7 @@ void WebView::repaint(const WebCore::IntRect& windowRect, bool contentChanged, b
 
 void WebView::deleteBackingStore()
 {
-    pendingDeleteBackingStoreSet.remove(this);
+    pendingDeleteBackingStoreSet().remove(this);
 
     if (m_deleteBackingStoreTimerActive) {
         KillTimer(m_viewWindow, DeleteBackingStoreTimer);
@@ -843,34 +885,34 @@ void WebView::addToDirtyRegion(const IntRect& dirtyRect)
     // but it was being hit during our layout tests, and is being investigated in
     // http://webkit.org/b/29350.
 
-#if USE(ACCELERATED_COMPOSITING)
     if (isAcceleratedCompositing()) {
+#if USE(CA)
         m_backingLayer->setNeedsDisplayInRect(dirtyRect);
+#elif USE(TEXTURE_MAPPER_GL)
+        m_acceleratedCompositingContext->setNonCompositedContentsNeedDisplay(dirtyRect);
+#endif
         return;
     }
-#endif
 
     auto newRegion = adoptGDIObject(::CreateRectRgn(dirtyRect.x(), dirtyRect.y(),
         dirtyRect.maxX(), dirtyRect.maxY()));
-    addToDirtyRegion(std::move(newRegion));
+    addToDirtyRegion(WTF::move(newRegion));
 }
 
 void WebView::addToDirtyRegion(GDIObject<HRGN> newRegion)
 {
     m_needsDisplay = true;
 
-#if USE(ACCELERATED_COMPOSITING)
     ASSERT(!isAcceleratedCompositing());
-#endif
 
     LOCAL_GDI_COUNTER(0, __FUNCTION__);
 
     if (m_backingStoreDirtyRegion) {
         auto combinedRegion = adoptGDIObject(::CreateRectRgn(0, 0, 0, 0));
         ::CombineRgn(combinedRegion.get(), m_backingStoreDirtyRegion->get(), newRegion.get(), RGN_OR);
-        m_backingStoreDirtyRegion = SharedGDIObject<HRGN>::create(std::move(combinedRegion));
+        m_backingStoreDirtyRegion = SharedGDIObject<HRGN>::create(WTF::move(combinedRegion));
     } else
-        m_backingStoreDirtyRegion = SharedGDIObject<HRGN>::create(std::move(newRegion));
+        m_backingStoreDirtyRegion = SharedGDIObject<HRGN>::create(WTF::move(newRegion));
 
     if (m_uiDelegatePrivate)
         m_uiDelegatePrivate->webViewDidInvalidate(this);
@@ -880,14 +922,16 @@ void WebView::scrollBackingStore(FrameView* frameView, int dx, int dy, const Int
 {
     m_needsDisplay = true;
 
-#if USE(ACCELERATED_COMPOSITING)
     if (isAcceleratedCompositing()) {
         // FIXME: We should be doing something smarter here, like moving tiles around and painting
         // any newly-exposed tiles. <http://webkit.org/b/52714>
+#if USE(CA)
         m_backingLayer->setNeedsDisplayInRect(scrollViewRect);
+#elif USE(TEXTURE_MAPPER_GL)
+        m_acceleratedCompositingContext->scrollNonCompositedContents(scrollViewRect, IntSize(dx, dy));
+#endif
         return;
     }
-#endif
 
     LOCAL_GDI_COUNTER(0, __FUNCTION__);
 
@@ -918,7 +962,7 @@ void WebView::scrollBackingStore(FrameView* frameView, int dx, int dy, const Int
     GdiFlush();
 
     // Add the dirty region to the backing store's dirty region.
-    addToDirtyRegion(std::move(updateRegion));
+    addToDirtyRegion(WTF::move(updateRegion));
 
     if (m_uiDelegatePrivate)
         m_uiDelegatePrivate->webViewScrolled(this);
@@ -939,13 +983,17 @@ void WebView::sizeChanged(const IntSize& newSize)
     if (Frame* coreFrame = core(topLevelFrame()))
         coreFrame->view()->resize(newSize);
 
-#if USE(ACCELERATED_COMPOSITING) && USE(CA)
+#if USE(CA)
     if (m_layerTreeHost)
         m_layerTreeHost->resize();
+
     if (m_backingLayer) {
         m_backingLayer->setSize(newSize);
         m_backingLayer->setNeedsDisplay();
     }
+#elif USE(TEXTURE_MAPPER_GL)
+    if (m_acceleratedCompositingContext)
+        m_acceleratedCompositingContext->resizeRootLayer(newSize);
 #endif
 }
 
@@ -993,9 +1041,7 @@ static void getUpdateRects(HRGN region, const IntRect& dirtyRect, Vector<IntRect
 
 void WebView::updateBackingStore(FrameView* frameView, HDC dc, bool backingStoreCompletelyDirty, WindowsToPaint windowsToPaint)
 {
-#if USE(ACCELERATED_COMPOSITING)
     ASSERT(!isAcceleratedCompositing());
-#endif
 
     LOCAL_GDI_COUNTER(0, __FUNCTION__);
 
@@ -1076,18 +1122,22 @@ void WebView::paint(HDC dc, LPARAM options)
 {
     LOCAL_GDI_COUNTER(0, __FUNCTION__);
 
-#if USE(ACCELERATED_COMPOSITING) && USE(CA)
     if (isAcceleratedCompositing() && !usesLayeredWindow()) {
+#if USE(CA)
         m_layerTreeHost->flushPendingLayerChangesNow();
+#elif USE(TEXTURE_MAPPER_GL)
+        m_acceleratedCompositingContext->flushAndRenderLayers();
+#endif
         // Flushing might have taken us out of compositing mode.
         if (isAcceleratedCompositing()) {
+#if USE(CA)
             // FIXME: We need to paint into dc (if provided). <http://webkit.org/b/52578>
             m_layerTreeHost->paint();
+#endif
             ::ValidateRect(m_viewWindow, 0);
             return;
         }
     }
-#endif
 
     Frame* coreFrame = core(m_mainFrame);
     if (!coreFrame)
@@ -1194,7 +1244,7 @@ void WebView::paintIntoBackingStore(FrameView* frameView, HDC bitmapDC, const In
 
     COMPtr<IWebUIDelegatePrivate2> uiPrivate(Query, m_uiDelegate);
     if (uiPrivate)
-        uiPrivate->drawBackground(this, reinterpret_cast<OLE_HANDLE>(bitmapDC), &rect);
+        uiPrivate->drawBackground(this, bitmapDC, &rect);
 
     if (frameView && frameView->frame().contentRenderer()) {
         gc.clip(dirtyRect);
@@ -1233,14 +1283,19 @@ void WebView::frameRect(RECT* rect)
     ::GetWindowRect(m_viewWindow, rect);
 }
 
-class WindowCloseTimer : public WebCore::SuspendableTimer {
+class WindowCloseTimer final : public WebCore::SuspendableTimer {
 public:
     static WindowCloseTimer* create(WebView*);
 
 private:
-    WindowCloseTimer(ScriptExecutionContext*, WebView*);
-    virtual void contextDestroyed();
-    virtual void fired();
+    WindowCloseTimer(ScriptExecutionContext&, WebView*);
+
+    // ActiveDOMObject API.
+    void contextDestroyed() override;
+    const char* activeDOMObjectName() const override { return "WindowCloseTimer"; }
+
+    // SuspendableTimer API.
+    void fired() override;
 
     WebView* m_webView;
 };
@@ -1251,21 +1306,22 @@ WindowCloseTimer* WindowCloseTimer::create(WebView* webView)
     Frame* frame = core(webView->topLevelFrame());
     ASSERT(frame);
     if (!frame)
-        return 0;
+        return nullptr;
 
     Document* document = frame->document();
     ASSERT(document);
     if (!document)
-        return 0;
+        return nullptr;
 
-    return new WindowCloseTimer(document, webView);
+    auto closeTimer = new WindowCloseTimer(*document, webView);
+    closeTimer->suspendIfNeeded();
+    return closeTimer;
 }
 
-WindowCloseTimer::WindowCloseTimer(ScriptExecutionContext* context, WebView* webView)
+WindowCloseTimer::WindowCloseTimer(ScriptExecutionContext& context, WebView* webView)
     : SuspendableTimer(context)
     , m_webView(webView)
 {
-    ASSERT_ARG(context, context);
     ASSERT_ARG(webView, webView);
 }
 
@@ -1331,8 +1387,8 @@ bool WebView::canHandleRequest(const WebCore::ResourceRequest& request)
 
 String WebView::standardUserAgentWithApplicationName(const String& applicationName)
 {
-    DEFINE_STATIC_LOCAL(String, osVersion, (windowsVersionForUAString()));
-    DEFINE_STATIC_LOCAL(String, webKitVersion, (webKitVersionString()));
+    DEPRECATED_DEFINE_STATIC_LOCAL(String, osVersion, (windowsVersionForUAString()));
+    DEPRECATED_DEFINE_STATIC_LOCAL(String, webKitVersion, (webKitVersionString()));
 
     return makeString("Mozilla/5.0 (", osVersion, ") AppleWebKit/", webKitVersion, " (KHTML, like Gecko)", applicationName.isEmpty() ? "" : " ", applicationName);
 }
@@ -1402,7 +1458,7 @@ bool WebView::handleContextMenuEvent(WPARAM wParam, LPARAM lParam)
         m_uiDelegate->hasCustomMenuImplementation(&hasCustomMenus);
 
     if (hasCustomMenus)
-        m_uiDelegate->trackCustomPopupMenu((IWebView*)this, (OLE_HANDLE)(ULONG64)coreMenu->platformContextMenu(), &point);
+        m_uiDelegate->trackCustomPopupMenu((IWebView*)this, coreMenu->platformContextMenu(), &point);
     else {
         // Surprisingly, TPM_RIGHTBUTTON means that items are selectable with either the right OR left mouse button
         UINT flags = TPM_RIGHTBUTTON | TPM_TOPALIGN | TPM_VERPOSANIMATION | TPM_HORIZONTAL
@@ -1455,7 +1511,7 @@ bool WebView::onInitMenuPopup(WPARAM wParam, LPARAM /*lParam*/)
     if (!hasCustomMenus)
         return false;
 
-    m_uiDelegate->addCustomMenuDrawingData((IWebView*)this, (OLE_HANDLE)(ULONG64)menu);
+    m_uiDelegate->addCustomMenuDrawingData((IWebView*)this, menu);
     return true;
 }
 
@@ -1473,7 +1529,7 @@ bool WebView::onUninitMenuPopup(WPARAM wParam, LPARAM /*lParam*/)
     if (!hasCustomMenus)
         return false;
 
-    m_uiDelegate->cleanUpCustomMenuDrawingData((IWebView*)this, (OLE_HANDLE)(ULONG64)menu);
+    m_uiDelegate->cleanUpCustomMenuDrawingData((IWebView*)this, menu);
     return true;
 }
 
@@ -1550,7 +1606,7 @@ bool WebView::handleMouseEvent(UINT message, WPARAM wParam, LPARAM lParam)
     } else if (message == WM_MOUSELEAVE && m_mouseOutTracker) {
         // Once WM_MOUSELEAVE is fired windows clears this tracker
         // so there is no need to disable it ourselves.
-        m_mouseOutTracker.clear();
+        m_mouseOutTracker.reset();
         m_page->mainFrame().eventHandler().mouseMoved(mouseEvent);
         handled = true;
     } else if (message == WM_MOUSEMOVE) {
@@ -1559,7 +1615,7 @@ bool WebView::handleMouseEvent(UINT message, WPARAM wParam, LPARAM lParam)
         mouseEvent.setClickCount(globalClickCount);
         handled = m_page->mainFrame().eventHandler().mouseMoved(mouseEvent);
         if (!m_mouseOutTracker) {
-            m_mouseOutTracker = adoptPtr(new TRACKMOUSEEVENT);
+            m_mouseOutTracker = std::make_unique<TRACKMOUSEEVENT>();
             m_mouseOutTracker->cbSize = sizeof(TRACKMOUSEEVENT);
             m_mouseOutTracker->dwFlags = TME_LEAVE;
             m_mouseOutTracker->hwndTrack = m_viewWindow;
@@ -1617,7 +1673,7 @@ bool WebView::gestureNotify(WPARAM wParam, LPARAM lParam)
     bool canBeScrolled = false;
     if (m_gestureTargetNode) {
         for (RenderObject* renderer = m_gestureTargetNode->renderer(); renderer; renderer = renderer->parent()) {
-            if (renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()) {
+            if (is<RenderBox>(*renderer) && downcast<RenderBox>(*renderer).canBeScrolledAndHasScrollableArea()) {
                 canBeScrolled = true;
                 break;
             }
@@ -2067,9 +2123,9 @@ bool WebView::keyDown(WPARAM virtualKeyCode, LPARAM keyData, bool systemKeyDown)
     // FIXME: This logic should probably be in EventHandler::defaultArrowEventHandler().
     // FIXME: Should check that other modifiers aren't pressed.
     if (virtualKeyCode == VK_RIGHT && keyEvent.ctrlKey())
-        return m_page->goForward();
+        return m_page->backForward().goForward();
     if (virtualKeyCode == VK_LEFT && keyEvent.ctrlKey())
-        return m_page->goBack();
+        return m_page->backForward().goBack();
 
     // Need to scroll the page if the arrow keys, pgup/dn, or home/end are hit.
     ScrollDirection direction;
@@ -2141,7 +2197,7 @@ void WebView::setShouldInvertColors(bool shouldInvertColors)
 
     m_shouldInvertColors = shouldInvertColors;
 
-#if USE(ACCELERATED_COMPOSITING) && USE(CA)
+#if USE(CA)
     if (m_layerTreeHost)
         m_layerTreeHost->setShouldInvertColors(shouldInvertColors);
 #endif
@@ -2209,7 +2265,7 @@ LRESULT CALLBACK WebView::WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam,
     ASSERT(webView);
 
     // Windows Media Player has a modal message loop that will deliver messages
-    // to us at inappropriate times and we will crash if we handle them when
+    // to us at inappropriate times and we will crash if we handle them when:
     // they are delivered. We repost paint messages so that we eventually get
     // a chance to paint once the modal loop has exited, but other messages
     // aren't safe to repost, so we just drop them.
@@ -2322,7 +2378,7 @@ LRESULT CALLBACK WebView::WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam,
             HWND newFocusWnd = reinterpret_cast<HWND>(wParam);
             if (SUCCEEDED(webView->uiDelegate(&uiDelegate)) && uiDelegate
                 && SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegatePrivate, (void**) &uiDelegatePrivate)) && uiDelegatePrivate)
-                uiDelegatePrivate->webViewLostFocus(webView, (OLE_HANDLE)(ULONG64)newFocusWnd);
+                uiDelegatePrivate->webViewLostFocus(webView, newFocusWnd);
 
             FocusController& focusController = webView->page()->focusController();
             Frame& frame = focusController.focusedOrMainFrame();
@@ -2385,7 +2441,7 @@ LRESULT CALLBACK WebView::WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam,
                 RECT windowRect;
                 ::GetClientRect(hWnd, &windowRect);
                 ::InvalidateRect(hWnd, &windowRect, false);
-#if USE(ACCELERATED_COMPOSITING)
+#if USE(CA)
                 if (webView->isAcceleratedCompositing())
                     webView->m_backingLayer->setNeedsDisplay();
 #endif
@@ -2464,8 +2520,7 @@ LRESULT CALLBACK WebView::WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam,
             break;
     }
 
-    if (webView->needsDisplay() && message != WM_PAINT)
-        ::UpdateWindow(hWnd);
+    webView->updateWindowIfNeeded(hWnd, message);
 
     if (!handled)
         lResult = DefWindowProc(hWnd, message, wParam, lParam);
@@ -2474,6 +2529,24 @@ LRESULT CALLBACK WebView::WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam,
     return (message == WM_KEYDOWN || message == WM_SYSKEYDOWN || message == WM_KEYUP || message == WM_SYSKEYUP) ? !handled : lResult;
 }
 
+void WebView::updateWindowIfNeeded(HWND hWnd, UINT message)
+{
+    if (!needsDisplay())
+        return;
+
+    // Care should be taken when updating the window from the window procedure.
+    // Updating the window in response to e.g. WM_PARENTNOTIFY may cause reentrancy problems,
+    // because WM_PARENTNOTIFY is sent synchronously to the parent window when e.g. DestroyWindow() is called.
+
+    switch (message) {
+    case WM_PAINT:
+    case WM_PARENTNOTIFY:
+        return;
+    }
+
+    ::UpdateWindow(hWnd);
+}
+
 bool WebView::developerExtrasEnabled() const
 {
     if (m_preferences->developerExtrasDisabledByOverride())
@@ -2592,8 +2665,8 @@ bool WebView::canShowMIMEType(const String& mimeType)
         || MIMETypeRegistry::isSupportedMediaMIMEType(mimeType);
 
     if (!canShow && m_page) {
-        canShow = (m_page->pluginData().supportsMimeType(mimeType, PluginData::AllPlugins) && allowPlugins)
-            || m_page->pluginData().supportsMimeType(mimeType, PluginData::OnlyApplicationPlugins);
+        canShow = (m_page->pluginData().supportsWebVisibleMimeType(mimeType, PluginData::AllPlugins) && allowPlugins)
+            || m_page->pluginData().supportsWebVisibleMimeType(mimeType, PluginData::OnlyApplicationPlugins);
     }
 
     if (!canShow)
@@ -2665,7 +2738,7 @@ static void WebKitSetApplicationCachePathIfNecessary()
 #endif
 
     if (!path.isNull())
-        cacheStorage().setCacheDirectory(path);
+        ApplicationCacheStorage::singleton().setCacheDirectory(path);
 
     initialized = true;
 }
@@ -2686,8 +2759,8 @@ bool WebView::shouldInitializeTrackPointHack()
         L"Software\\Synaptics\\SynTPEnh\\UltraNavPS2" };
 
     for (int i = 0; i < 5; ++i) {
-        HKEY trackPointKey;
-        int readKeyResult = ::RegOpenKeyExW(HKEY_CURRENT_USER, trackPointKeys[i], 0, KEY_READ, &trackPointKey);
+        HKEY trackPointKey = nullptr;
+        LSTATUS readKeyResult = ::RegOpenKeyExW(HKEY_CURRENT_USER, trackPointKeys[i], 0, KEY_READ, &trackPointKey);
         ::RegCloseKey(trackPointKey);
         if (readKeyResult == ERROR_SUCCESS) {
             shouldCreateScrollbars = true;
@@ -2697,7 +2770,7 @@ bool WebView::shouldInitializeTrackPointHack()
 
     return shouldCreateScrollbars;
 }
-    
+
 HRESULT STDMETHODCALLTYPE WebView::initWithFrame( 
     /* [in] */ RECT frame,
     /* [in] */ BSTR frameName,
@@ -2740,48 +2813,37 @@ HRESULT STDMETHODCALLTYPE WebView::initWithFrame(
         // of the initialization code which may depend on the strategies.
         WebPlatformStrategies::initialize();
 
-#if ENABLE(SQL_DATABASE)
         WebKitInitializeWebDatabasesIfNecessary();
-#endif
         WebKitSetApplicationCachePathIfNecessary();
-        Settings::setDefaultMinDOMTimerInterval(0.004);
 
         didOneTimeInitialization = true;
      }
 
-#if USE(SAFARI_THEME)
-    BOOL shouldPaintNativeControls;
-    if (SUCCEEDED(m_preferences->shouldPaintNativeControls(&shouldPaintNativeControls)))
-        Settings::setShouldPaintNativeControls(shouldPaintNativeControls);
-#endif
-
     BOOL useHighResolutionTimer;
     if (SUCCEEDED(m_preferences->shouldUseHighResolutionTimers(&useHighResolutionTimer)))
         Settings::setShouldUseHighResolutionTimers(useHighResolutionTimer);
 
-#if ENABLE(INSPECTOR)
     m_inspectorClient = new WebInspectorClient(this);
-#endif // ENABLE(INSPECTOR)
-
-    Page::PageClients pageClients;
-    pageClients.chromeClient = new WebChromeClient(this);
-    pageClients.contextMenuClient = new WebContextMenuClient(this);
-    pageClients.editorClient = new WebEditorClient(this);
-    pageClients.dragClient = new WebDragClient(this);
-#if ENABLE(INSPECTOR)
-    pageClients.inspectorClient = m_inspectorClient;
-#endif // ENABLE(INSPECTOR)
-    pageClients.loaderClientForMainFrame = new WebFrameLoaderClient;
-
-    m_page = new Page(pageClients);
+
+    PageConfiguration configuration;
+    configuration.chromeClient = new WebChromeClient(this);
+    configuration.contextMenuClient = new WebContextMenuClient(this);
+    configuration.editorClient = new WebEditorClient(this);
+    configuration.dragClient = new WebDragClient(this);
+    configuration.inspectorClient = m_inspectorClient;
+    configuration.loaderClientForMainFrame = new WebFrameLoaderClient;
+    configuration.databaseProvider = &WebDatabaseProvider::singleton();
+    configuration.storageNamespaceProvider = &m_webViewGroup->storageNamespaceProvider();
+    configuration.progressTrackerClient = static_cast<WebFrameLoaderClient*>(configuration.loaderClientForMainFrame);
+    configuration.userContentController = &m_webViewGroup->userContentController();
+    configuration.visitedLinkStore = &m_webViewGroup->visitedLinkStore();
+
+    m_page = new Page(configuration);
     provideGeolocationTo(m_page, new WebGeolocationClient(this));
 
     unsigned layoutMilestones = DidFirstLayout | DidFirstVisuallyNonEmptyLayout;
     m_page->addLayoutMilestones(static_cast<LayoutMilestones>(layoutMilestones));
 
-    BString localStoragePath;
-    if (SUCCEEDED(m_preferences->localStorageDatabasePath(&localStoragePath)))
-        m_page->settings().setLocalStorageDatabasePath(toString(localStoragePath));
 
     if (m_uiDelegate) {
         BString path;
@@ -2812,6 +2874,8 @@ HRESULT STDMETHODCALLTYPE WebView::initWithFrame(
     notifyCenter->addObserver(this, WebPreferences::webPreferencesChangedNotification(), static_cast<IWebPreferences*>(m_preferences.get()));
     m_preferences->postPreferencesChangesNotification();
 
+    m_page->setDeviceScaleFactor(deviceScaleFactor());
+
     setSmartInsertDeleteEnabled(TRUE);
     return hr;
 }
@@ -2884,7 +2948,7 @@ HRESULT WebView::notifyDidAddIcon(IWebNotification* notification)
         return E_FAIL;
 
     COMVariant iconUserInfoURL;
-    hr = propertyBag->Read(WebIconDatabase::iconDatabaseNotificationUserInfoURLKey(), &iconUserInfoURL, 0);
+    hr = propertyBag->Read(WebIconDatabase::iconDatabaseNotificationUserInfoURLKey(), &iconUserInfoURL, nullptr);
     if (FAILED(hr))
         return hr;
 
@@ -2921,7 +2985,7 @@ void WebView::dispatchDidReceiveIconFromWebFrame(WebFrame* frame)
 
         BitmapInfo bmInfo = BitmapInfo::create(sz);
 
-        HBITMAP hBitmap = 0;
+        HBITMAP hBitmap = nullptr;
 
         Image* icon = iconDatabase().synchronousIconForPageURL(str, sz);
 
@@ -2931,8 +2995,8 @@ void WebView::dispatchDidReceiveIconFromWebFrame(WebFrame* frame)
             icon->getHBITMAPOfSize(hBitmap, &sz);
         }
 
-        HRESULT hr = m_frameLoadDelegate->didReceiveIcon(this, (OLE_HANDLE)hBitmap, frame);
-        if (hr == E_NOTIMPL)
+        HRESULT hr = m_frameLoadDelegate->didReceiveIcon(this, hBitmap, frame);
+        if ((hr == E_NOTIMPL) && hBitmap)
             DeleteObject(hBitmap);
     }
 }
@@ -3083,7 +3147,7 @@ HRESULT STDMETHODCALLTYPE WebView::backForwardList(
     if (!m_useBackForwardList)
         return E_FAIL;
  
-    *list = WebBackForwardList::createInstance(static_cast<WebCore::BackForwardList*>(m_page->backForwardClient()));
+    *list = WebBackForwardList::createInstance(static_cast<WebCore::BackForwardList*>(m_page->backForward().client()));
 
     return S_OK;
 }
@@ -3098,14 +3162,14 @@ HRESULT STDMETHODCALLTYPE WebView::setMaintainsBackForwardList(
 HRESULT STDMETHODCALLTYPE WebView::goBack( 
     /* [retval][out] */ BOOL* succeeded)
 {
-    *succeeded = m_page->goBack();
+    *succeeded = m_page->backForward().goBack();
     return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE WebView::goForward( 
     /* [retval][out] */ BOOL* succeeded)
 {
-    *succeeded = m_page->goForward();
+    *succeeded = m_page->backForward().goForward();
     return S_OK;
 }
 
@@ -3120,7 +3184,7 @@ HRESULT STDMETHODCALLTYPE WebView::goToBackForwardItem(
     if (FAILED(hr))
         return hr;
 
-    m_page->goToItem(webHistoryItem->historyItem(), FrameLoadTypeIndexedBackForward);
+    m_page->goToItem(*webHistoryItem->historyItem(), FrameLoadType::IndexedBackForward);
     *succeeded = TRUE;
 
     return S_OK;
@@ -3189,7 +3253,7 @@ HRESULT STDMETHODCALLTYPE WebView::setApplicationNameForUserAgent(
 HRESULT STDMETHODCALLTYPE WebView::applicationNameForUserAgent( 
     /* [retval][out] */ BSTR* applicationName)
 {
-    *applicationName = SysAllocStringLen(m_applicationName.characters(), m_applicationName.length());
+    *applicationName = BString(m_applicationName).release();
     if (!*applicationName && m_applicationName.length())
         return E_OUTOFMEMORY;
     return S_OK;
@@ -3209,7 +3273,7 @@ HRESULT STDMETHODCALLTYPE WebView::customUserAgent(
     *userAgentString = 0;
     if (!m_userAgentOverridden)
         return S_OK;
-    *userAgentString = SysAllocStringLen(m_userAgentCustom.characters(), m_userAgentCustom.length());
+    *userAgentString = BString(m_userAgentCustom).release();
     if (!*userAgentString && m_userAgentCustom.length())
         return E_OUTOFMEMORY;
     return S_OK;
@@ -3432,17 +3496,17 @@ void WebView::updateActiveStateSoon() const
 
 void WebView::deleteBackingStoreSoon()
 {
-    if (pendingDeleteBackingStoreSet.size() > 2) {
+    if (pendingDeleteBackingStoreSet().size() > 2) {
         Vector<WebView*> views;
-        HashSet<WebView*>::iterator end = pendingDeleteBackingStoreSet.end();
-        for (HashSet<WebView*>::iterator it = pendingDeleteBackingStoreSet.begin(); it != end; ++it)
+        HashSet<WebView*>::iterator end = pendingDeleteBackingStoreSet().end();
+        for (HashSet<WebView*>::iterator it = pendingDeleteBackingStoreSet().begin(); it != end; ++it)
             views.append(*it);
         for (int i = 0; i < views.size(); ++i)
             views[i]->deleteBackingStore();
-        ASSERT(pendingDeleteBackingStoreSet.isEmpty());
+        ASSERT(pendingDeleteBackingStoreSet().isEmpty());
     }
 
-    pendingDeleteBackingStoreSet.add(this);
+    pendingDeleteBackingStoreSet().add(this);
     m_deleteBackingStoreTimerActive = true;
     SetTimer(m_viewWindow, DeleteBackingStoreTimer, delayBeforeDeletingBackingStoreMsec, 0);
 }
@@ -3451,15 +3515,13 @@ void WebView::cancelDeleteBackingStoreSoon()
 {
     if (!m_deleteBackingStoreTimerActive)
         return;
-    pendingDeleteBackingStoreSet.remove(this);
+    pendingDeleteBackingStoreSet().remove(this);
     m_deleteBackingStoreTimerActive = false;
     KillTimer(m_viewWindow, DeleteBackingStoreTimer);
 }
 
-HRESULT STDMETHODCALLTYPE WebView::setHostWindow( 
-    /* [in] */ OLE_HANDLE oleWindow)
+HRESULT WebView::setHostWindow(/* [in] */ HWND window)
 {
-    HWND window = (HWND)(ULONG64)oleWindow;
     if (m_viewWindow) {
         if (window)
             SetParent(m_viewWindow, window);
@@ -3476,13 +3538,15 @@ HRESULT STDMETHODCALLTYPE WebView::setHostWindow(
 
     windowAncestryDidChange();
 
+    if (m_page)
+        m_page->setDeviceScaleFactor(deviceScaleFactor());
+
     return S_OK;
 }
 
-HRESULT STDMETHODCALLTYPE WebView::hostWindow( 
-    /* [retval][out] */ OLE_HANDLE* window)
+HRESULT WebView::hostWindow(/* [retval][out] */ HWND* window)
 {
-    *window = (OLE_HANDLE)(ULONG64)m_hostWindow;
+    *window = m_hostWindow;
     return S_OK;
 }
 
@@ -3605,14 +3669,14 @@ HRESULT STDMETHODCALLTYPE WebView::rectsForTextMatches(
     return createMatchEnumerator(&allRects, pmatches);
 }
 
-HRESULT STDMETHODCALLTYPE WebView::generateSelectionImage(BOOL forceWhiteText, OLE_HANDLE* hBitmap)
+HRESULT STDMETHODCALLTYPE WebView::generateSelectionImage(BOOL forceWhiteText, HBITMAP* hBitmap)
 {
     *hBitmap = 0;
 
     WebCore::Frame& frame = m_page->focusController().focusedOrMainFrame();
 
     auto bitmap = imageFromSelection(&frame, forceWhiteText ? TRUE : FALSE);
-    *hBitmap = static_cast<OLE_HANDLE>(reinterpret_cast<ULONG64>(bitmap.leak()));
+    *hBitmap = bitmap.leak();
 
     return S_OK;
 }
@@ -3621,7 +3685,7 @@ HRESULT STDMETHODCALLTYPE WebView::selectionRect(RECT* rc)
 {
     WebCore::Frame& frame = m_page->focusController().focusedOrMainFrame();
 
-    IntRect ir = enclosingIntRect(frame.selection().bounds());
+    IntRect ir = enclosingIntRect(frame.selection().selectionBounds());
     ir = frame.view()->convertToContainingWindow(ir);
     ir.move(-frame.view()->scrollOffset().width(), -frame.view()->scrollOffset().height());
     rc->left = ir.x();
@@ -3644,8 +3708,17 @@ HRESULT STDMETHODCALLTYPE WebView::registerViewClass(
 HRESULT STDMETHODCALLTYPE WebView::setGroupName( 
         /* [in] */ BSTR groupName)
 {
+    if (m_webViewGroup)
+        m_webViewGroup->removeWebView(this);
+
+    m_webViewGroup = WebViewGroup::getOrCreate(groupName, localStorageDatabasePath(m_preferences.get()));
+    m_webViewGroup->addWebView(this);
+
     if (!m_page)
         return S_OK;
+
+    m_page->setUserContentController(&m_webViewGroup->userContentController());
+    m_page->setVisitedLinkStore(m_webViewGroup->visitedLinkStore());
     m_page->setGroupName(toString(groupName));
     return S_OK;
 }
@@ -3657,7 +3730,7 @@ HRESULT STDMETHODCALLTYPE WebView::groupName(
     if (!m_page)
         return S_OK;
     String groupNameString = m_page->groupName();
-    *groupName = SysAllocStringLen(groupNameString.characters(), groupNameString.length());
+    *groupName = BString(groupNameString).release();
     if (!*groupName && groupNameString.length())
         return E_OUTOFMEMORY;
     return S_OK;
@@ -3767,7 +3840,7 @@ HRESULT STDMETHODCALLTYPE WebView::selectedText(
         return E_FAIL;
 
     String frameSelectedText = focusedFrame->editor().selectedText();
-    *text = SysAllocStringLen(frameSelectedText.characters(), frameSelectedText.length());
+    *text = BString(frameSelectedText).release();
     if (!*text && frameSelectedText.length())
         return E_OUTOFMEMORY;
     return S_OK;
@@ -3867,8 +3940,7 @@ HRESULT STDMETHODCALLTYPE WebView::mainFrameTitle(
     return E_NOTIMPL;
 }
     
-HRESULT STDMETHODCALLTYPE WebView::mainFrameIcon( 
-        /* [retval][out] */ OLE_HANDLE* /*hBitmap*/)
+HRESULT WebView::mainFrameIcon(/* [retval][out] */ HBITMAP* /*hBitmap*/)
 {
     ASSERT_NOT_REACHED();
     return E_NOTIMPL;
@@ -3916,7 +3988,7 @@ HRESULT STDMETHODCALLTYPE WebView::canGoBack(
         /* [in] */ IUnknown* /*sender*/,
         /* [retval][out] */ BOOL* result)
 {
-    *result = !!(m_page->backForwardClient()->backItem() && !m_page->defersLoading());
+    *result = !!(m_page->backForward().backItem() && !m_page->defersLoading());
     return S_OK;
 }
     
@@ -3931,7 +4003,7 @@ HRESULT STDMETHODCALLTYPE WebView::canGoForward(
         /* [in] */ IUnknown* /*sender*/,
         /* [retval][out] */ BOOL* result)
 {
-    *result = !!(m_page->backForwardClient()->forwardItem() && !m_page->defersLoading());
+    *result = !!(m_page->backForward().forwardItem() && !m_page->defersLoading());
     return S_OK;
 }
     
@@ -4147,8 +4219,7 @@ HRESULT STDMETHODCALLTYPE WebView::setSelectedDOMRange(
     return E_NOTIMPL;
 }
     
-HRESULT STDMETHODCALLTYPE WebView::selectedDOMRange( 
-        /* [retval][out] */ IDOMRange** /*range*/)
+HRESULT WebView::selectedDOMRange(IDOMRange** range)
 {
     ASSERT_NOT_REACHED();
     return E_NOTIMPL;
@@ -4161,18 +4232,34 @@ HRESULT STDMETHODCALLTYPE WebView::selectionAffinity(
     return E_NOTIMPL;
 }
     
-HRESULT STDMETHODCALLTYPE WebView::setEditable( 
-        /* [in] */ BOOL /*flag*/)
+HRESULT WebView::setEditable(BOOL flag)
 {
-    ASSERT_NOT_REACHED();
-    return E_NOTIMPL;
+    if (!m_page)
+        return S_OK;
+
+    if (m_page->isEditable() == static_cast<bool>(flag))
+        return S_OK;
+
+    m_page->setEditable(flag);
+    if (!m_page->tabKeyCyclesThroughElements())
+        m_page->setTabKeyCyclesThroughElements(!flag);
+
+    return S_OK;
 }
     
-HRESULT STDMETHODCALLTYPE WebView::isEditable( 
-        /* [retval][out] */ BOOL* /*isEditable*/)
+HRESULT WebView::isEditable(BOOL* isEditable)
 {
-    ASSERT_NOT_REACHED();
-    return E_NOTIMPL;
+    if (!isEditable)
+        return E_POINTER;
+
+    if (!m_page) {
+        *isEditable = FALSE;
+        return S_OK;
+    }
+
+    *isEditable = m_page->isEditable();
+
+    return S_OK;
 }
     
 HRESULT STDMETHODCALLTYPE WebView::setTypingStyle( 
@@ -4310,10 +4397,39 @@ HRESULT STDMETHODCALLTYPE WebView::undoManager(
     return E_NOTIMPL;
 }
     
-HRESULT STDMETHODCALLTYPE WebView::setEditingDelegate( 
-        /* [in] */ IWebEditingDelegate* d)
+HRESULT WebView::setEditingDelegate(IWebEditingDelegate* d)
 {
+    if (m_editingDelegate == d)
+        return S_OK;
+
+    static BSTR webViewDidBeginEditingNotificationName = SysAllocString(WebViewDidBeginEditingNotification);
+    static BSTR webViewDidChangeSelectionNotificationName = SysAllocString(WebViewDidChangeSelectionNotification);
+    static BSTR webViewDidEndEditingNotificationName = SysAllocString(WebViewDidEndEditingNotification);
+    static BSTR webViewDidChangeTypingStyleNotificationName = SysAllocString(WebViewDidChangeTypingStyleNotification);
+    static BSTR webViewDidChangeNotificationName = SysAllocString(WebViewDidChangeNotification);
+
+    IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+
+    COMPtr<IWebNotificationObserver> wasObserver(Query, m_editingDelegate);
+    if (wasObserver) {
+        notifyCenter->removeObserver(wasObserver.get(), webViewDidBeginEditingNotificationName, nullptr);
+        notifyCenter->removeObserver(wasObserver.get(), webViewDidChangeSelectionNotificationName, nullptr);
+        notifyCenter->removeObserver(wasObserver.get(), webViewDidEndEditingNotificationName, nullptr);
+        notifyCenter->removeObserver(wasObserver.get(), webViewDidChangeTypingStyleNotificationName, nullptr);
+        notifyCenter->removeObserver(wasObserver.get(), webViewDidChangeNotificationName, nullptr);
+    }
+
     m_editingDelegate = d;
+
+    COMPtr<IWebNotificationObserver> isObserver(Query, m_editingDelegate);
+    if (isObserver) {
+        notifyCenter->addObserver(isObserver.get(), webViewDidBeginEditingNotificationName, nullptr);
+        notifyCenter->addObserver(isObserver.get(), webViewDidChangeSelectionNotificationName, nullptr);
+        notifyCenter->addObserver(isObserver.get(), webViewDidEndEditingNotificationName, nullptr);
+        notifyCenter->addObserver(isObserver.get(), webViewDidChangeTypingStyleNotificationName, nullptr);
+        notifyCenter->addObserver(isObserver.get(), webViewDidChangeNotificationName, nullptr);
+    }
+
     return S_OK;
 }
     
@@ -4684,6 +4800,7 @@ HRESULT WebView::notifyPreferencesChanged(IWebNotification* notification)
 
     BString str;
     int size;
+    unsigned javaScriptRuntimeFlags;
     BOOL enabled;
 
     Settings& settings = m_page->settings();
@@ -4789,11 +4906,6 @@ HRESULT WebView::notifyPreferencesChanged(IWebNotification* notification)
         return hr;
     RuntimeEnabledFeatures::sharedFeatures().setCSSRegionsEnabled(!!enabled);
 
-    hr = preferences->areSeamlessIFramesEnabled(&enabled);
-    if (FAILED(hr))
-        return hr;
-    RuntimeEnabledFeatures::sharedFeatures().setSeamlessIFramesEnabled(!!enabled);
-
     hr = preferences->privateBrowsingEnabled(&enabled);
     if (FAILED(hr))
         return hr;
@@ -4803,7 +4915,7 @@ HRESULT WebView::notifyPreferencesChanged(IWebNotification* notification)
     else
         WebFrameNetworkingContext::destroyPrivateBrowsingSession();
 #endif
-    settings.setPrivateBrowsingEnabled(!!enabled);
+    m_page->enableLegacyPrivateBrowsing(!!enabled);
 
     hr = preferences->sansSerifFontFamily(&str);
     if (FAILED(hr))
@@ -4916,22 +5028,15 @@ HRESULT WebView::notifyPreferencesChanged(IWebNotification* notification)
         settings.setAuthorAndUserStylesEnabled(enabled);
     }
 
-    hr = prefsPrivate->inApplicationChromeMode(&enabled);
-    if (FAILED(hr))
-        return hr;
-    settings.setApplicationChromeMode(enabled);
-
     hr = prefsPrivate->offlineWebApplicationCacheEnabled(&enabled);
     if (FAILED(hr))
         return hr;
     settings.setOfflineWebApplicationCacheEnabled(enabled);
 
-#if ENABLE(SQL_DATABASE)
     hr = prefsPrivate->databasesEnabled(&enabled);
     if (FAILED(hr))
         return hr;
-    DatabaseManager::manager().setIsAvailable(enabled);
-#endif
+    DatabaseManager::singleton().setIsAvailable(enabled);
 
     hr = prefsPrivate->localStorageEnabled(&enabled);
     if (FAILED(hr))
@@ -4968,13 +5073,6 @@ HRESULT WebView::notifyPreferencesChanged(IWebNotification* notification)
         return hr;
     settings.setXSSAuditorEnabled(!!enabled);
 
-#if USE(SAFARI_THEME)
-    hr = prefsPrivate->shouldPaintNativeControls(&enabled);
-    if (FAILED(hr))
-        return hr;
-    settings.setShouldPaintNativeControls(!!enabled);
-#endif
-
     hr = prefsPrivate->shouldUseHighResolutionTimers(&enabled);
     if (FAILED(hr))
         return hr;
@@ -4985,12 +5083,14 @@ HRESULT WebView::notifyPreferencesChanged(IWebNotification* notification)
         return hr;
     settings.setFrameFlatteningEnabled(enabled);
 
-#if USE(ACCELERATED_COMPOSITING)
     hr = prefsPrivate->acceleratedCompositingEnabled(&enabled);
     if (FAILED(hr))
         return hr;
-    settings.setAcceleratedCompositingEnabled(enabled);
+#if USE(TEXTURE_MAPPER_GL)
+    static bool acceleratedCompositingAvailable = AcceleratedCompositingContext::acceleratedCompositingAvailable();
+    enabled = enabled && acceleratedCompositingAvailable;
 #endif
+    settings.setAcceleratedCompositingEnabled(enabled);
 
     hr = prefsPrivate->showDebugBorders(&enabled);
     if (FAILED(hr))
@@ -5048,12 +5148,12 @@ HRESULT WebView::notifyPreferencesChanged(IWebNotification* notification)
     hr = prefsPrivate->mediaPlaybackRequiresUserGesture(&enabled);
     if (FAILED(hr))
         return hr;
-    settings.setMediaPlaybackRequiresUserGesture(enabled);
+    settings.setRequiresUserGestureForMediaPlayback(enabled);
 
     hr = prefsPrivate->mediaPlaybackAllowsInline(&enabled);
     if (FAILED(hr))
         return hr;
-    settings.setMediaPlaybackAllowsInline(enabled);
+    settings.setAllowsInlineMediaPlayback(enabled);
 
     hr = prefsPrivate->shouldInvertColors(&enabled);
     if (FAILED(hr))
@@ -5065,6 +5165,21 @@ HRESULT WebView::notifyPreferencesChanged(IWebNotification* notification)
         return hr;
     settings.setRequestAnimationFrameEnabled(enabled);
 
+    hr = prefsPrivate->mockScrollbarsEnabled(&enabled);
+    if (FAILED(hr))
+        return hr;
+    settings.setMockScrollbarsEnabled(enabled);
+
+    hr = prefsPrivate->isInheritURIQueryComponentEnabled(&enabled);
+    if (FAILED(hr))
+        return hr;
+    settings.setEnableInheritURIQueryComponent(enabled);
+
+    hr = prefsPrivate->javaScriptRuntimeFlags(&javaScriptRuntimeFlags);
+    if (FAILED(hr))
+        return hr;
+    settings.setJavaScriptRuntimeFlags(JSC::RuntimeFlags(javaScriptRuntimeFlags));
+
     return S_OK;
 }
 
@@ -5122,25 +5237,18 @@ HRESULT STDMETHODCALLTYPE WebView::removeCustomDropTarget()
 HRESULT STDMETHODCALLTYPE WebView::setInViewSourceMode( 
         /* [in] */ BOOL flag)
 {
-    if (!m_mainFrame)
-        return E_FAIL;
-
-    return m_mainFrame->setInViewSourceMode(flag);
+    return E_NOTIMPL;
 }
     
 HRESULT STDMETHODCALLTYPE WebView::inViewSourceMode( 
         /* [retval][out] */ BOOL* flag)
 {
-    if (!m_mainFrame)
-        return E_FAIL;
-
-    return m_mainFrame->inViewSourceMode(flag);
+    return E_NOTIMPL;
 }
 
-HRESULT STDMETHODCALLTYPE WebView::viewWindow( 
-        /* [retval][out] */ OLE_HANDLE *window)
+HRESULT WebView::viewWindow(/* [retval][out] */ HWND* window)
 {
-    *window = (OLE_HANDLE)(ULONG64)m_viewWindow;
+    *window = m_viewWindow;
     return S_OK;
 }
 
@@ -5163,7 +5271,23 @@ HRESULT STDMETHODCALLTYPE WebView::formDelegate(
 HRESULT STDMETHODCALLTYPE WebView::setFrameLoadDelegatePrivate( 
     /* [in] */ IWebFrameLoadDelegatePrivate* d)
 {
+    if (m_frameLoadDelegatePrivate == d)
+        return S_OK;
+
+    static BSTR webViewProgressFinishedNotificationName = SysAllocString(WebViewProgressFinishedNotification);
+
+    IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+
+    COMPtr<IWebNotificationObserver> wasObserver(Query, m_frameLoadDelegatePrivate);
+    if (wasObserver)
+        notifyCenter->removeObserver(wasObserver.get(), webViewProgressFinishedNotificationName, nullptr);
+
     m_frameLoadDelegatePrivate = d;
+
+    COMPtr<IWebNotificationObserver> isObserver(Query, m_frameLoadDelegatePrivate);
+    if (isObserver)
+        notifyCenter->addObserver(isObserver.get(), webViewProgressFinishedNotificationName, nullptr);
+
     return S_OK;
 }
 
@@ -5255,7 +5379,7 @@ HRESULT STDMETHODCALLTYPE WebView::DragEnter(
     ::ScreenToClient(m_viewWindow, (LPPOINT)&localpt);
     DragData data(pDataObject, IntPoint(localpt.x, localpt.y), 
         IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
-    *pdwEffect = dragOperationToDragCursor(m_page->dragController().dragEntered(data).operation);
+    *pdwEffect = dragOperationToDragCursor(m_page->dragController().dragEntered(data));
 
     m_lastDropEffect = *pdwEffect;
     m_dragData = pDataObject;
@@ -5274,7 +5398,7 @@ HRESULT STDMETHODCALLTYPE WebView::DragOver(
         ::ScreenToClient(m_viewWindow, (LPPOINT)&localpt);
         DragData data(m_dragData.get(), IntPoint(localpt.x, localpt.y), 
             IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
-        *pdwEffect = dragOperationToDragCursor(m_page->dragController().dragUpdated(data).operation);
+        *pdwEffect = dragOperationToDragCursor(m_page->dragController().dragUpdated(data));
     } else
         *pdwEffect = DROPEFFECT_NONE;
 
@@ -5308,7 +5432,7 @@ HRESULT STDMETHODCALLTYPE WebView::Drop(
     ::ScreenToClient(m_viewWindow, (LPPOINT)&localpt);
     DragData data(pDataObject, IntPoint(localpt.x, localpt.y), 
         IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
-    m_page->dragController().performDrag(data);
+    m_page->dragController().performDragOperation(data);
     return S_OK;
 }
 
@@ -5326,17 +5450,13 @@ HRESULT STDMETHODCALLTYPE WebView::canHandleRequest(
     return S_OK;
 }
 
-HRESULT STDMETHODCALLTYPE WebView::standardUserAgentWithApplicationName( 
-    BSTR applicationName,
-    BSTR* groupName)
+HRESULT WebView::standardUserAgentWithApplicationName(BSTR applicationName, BSTR* groupName)
 {
     if (!groupName) {
         ASSERT_NOT_REACHED();
         return E_POINTER;
     }
 
-    *groupName;
-
     if (!applicationName) {
         ASSERT_NOT_REACHED();
         return E_POINTER;
@@ -5410,34 +5530,34 @@ HRESULT STDMETHODCALLTYPE WebView::loadBackForwardListFromOtherView(
     // It turns out the right combination of behavior is done with the back/forward load
     // type.  (See behavior matrix at the top of WebFramePrivate.)  So we copy all the items
     // in the back forward list, and go to the current one.
-    BackForwardClient* backForwardClient = m_page->backForwardClient();
-    ASSERT(!backForwardClient->currentItem()); // destination list should be empty
+    BackForwardController& backForward = m_page->backForward();
+    ASSERT(!backForward.currentItem()); // destination list should be empty
 
     COMPtr<WebView> otherWebView;
     if (FAILED(otherView->QueryInterface(&otherWebView)))
         return E_FAIL;
-    BackForwardClient* otherBackForwardClient = otherWebView->m_page->backForwardClient();
-    if (!otherBackForwardClient->currentItem())
+    BackForwardController& otherBackForward = otherWebView->m_page->backForward();
+    if (!otherBackForward.currentItem())
         return S_OK; // empty back forward list, bail
     
     HistoryItem* newItemToGoTo = 0;
 
-    int lastItemIndex = otherBackForwardClient->forwardListCount();
-    for (int i = -otherBackForwardClient->backListCount(); i <= lastItemIndex; ++i) {
+    int lastItemIndex = otherBackForward.forwardCount();
+    for (int i = -otherBackForward.backCount(); i <= lastItemIndex; ++i) {
         if (!i) {
             // 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().history().saveDocumentAndScrollState();
         }
-        RefPtr<HistoryItem> newItem = otherBackForwardClient->itemAtIndex(i)->copy();
+        Ref<HistoryItem> newItem = otherBackForward.itemAtIndex(i)->copy();
         if (!i) 
-            newItemToGoTo = newItem.get();
-        backForwardClient->addItem(newItem.release());
+            newItemToGoTo = newItem.ptr();
+        backForward.client()->addItem(WTF::move(newItem));
     }
     
     ASSERT(newItemToGoTo);
-    m_page->goToItem(newItemToGoTo, FrameLoadTypeIndexedBackForward);
+    m_page->goToItem(*newItemToGoTo, FrameLoadType::IndexedBackForward);
     return S_OK;
 }
 
@@ -5485,7 +5605,7 @@ HRESULT WebView::setProhibitsMainFrameScrolling(BOOL b)
 
 HRESULT WebView::setShouldApplyMacFontAscentHack(BOOL b)
 {
-    SimpleFontData::setShouldApplyMacAscentHack(b);
+    Font::setShouldApplyMacAscentHack(b);
     return S_OK;
 }
 
@@ -5586,7 +5706,7 @@ void WebView::resetIME(Frame* targetFrame)
 void WebView::updateSelectionForIME()
 {
     Frame& targetFrame = m_page->focusController().focusedOrMainFrame();
-    if (!targetFrame.editor().cancelCompositionIfSelectionIsInvalid())
+    if (targetFrame.editor().cancelCompositionIfSelectionIsInvalid())
         resetIME(&targetFrame);
 }
 
@@ -5841,7 +5961,7 @@ LRESULT WebView::onIMERequestReconvertString(Frame* targetFrame, RECONVERTSTRING
     reconvertString->dwStrLen = text.length();
     reconvertString->dwTargetStrLen = text.length();
     reconvertString->dwStrOffset = sizeof(RECONVERTSTRING);
-    memcpy(reconvertString + 1, text.characters(), text.length() * sizeof(UChar));
+    StringView(text).getCharactersWithUpconvert(reinterpret_cast<UChar*>(reconvertString + 1));
     return totalSize;
 }
 
@@ -5878,14 +5998,10 @@ bool WebView::onIMESetContext(WPARAM wparam, LPARAM)
 
 HRESULT STDMETHODCALLTYPE WebView::inspector(IWebInspector** inspector)
 {
-#if ENABLE(INSPECTOR)
     if (!m_webInspector)
         m_webInspector.adoptRef(WebInspector::createInstance(this, m_inspectorClient));
 
     return m_webInspector.copyRefTo(inspector);
-#else // !ENABLE(INSPECTOR)
-    return S_OK;
-#endif // ENABLE(INSPECTOR)
 }
 
 
@@ -5911,14 +6027,15 @@ HRESULT STDMETHODCALLTYPE WebView::windowAncestryDidChange()
     if (m_topLevelParent)
         WindowMessageBroadcaster::addListener(m_topLevelParent, this);
 
+    if (m_page)
+        m_page->setDeviceScaleFactor(deviceScaleFactor());
+
     updateActiveState();
 
     return S_OK;
 }
 
-HRESULT STDMETHODCALLTYPE WebView::paintDocumentRectToContext(
-    /* [in] */ RECT rect,
-    /* [in] */ OLE_HANDLE deviceContext)
+HRESULT WebView::paintDocumentRectToContext(RECT rect, HDC deviceContext)
 {
     if (!deviceContext)
         return E_POINTER;
@@ -5929,10 +6046,7 @@ HRESULT STDMETHODCALLTYPE WebView::paintDocumentRectToContext(
     return m_mainFrame->paintDocumentRectToContext(rect, deviceContext);
 }
 
-HRESULT STDMETHODCALLTYPE WebView::paintScrollViewRectToContextAtPoint(
-    /* [in] */ RECT rect,
-    /* [in] */ POINT pt,
-    /* [in] */ OLE_HANDLE deviceContext)
+HRESULT WebView::paintScrollViewRectToContextAtPoint(RECT rect, POINT pt, HDC deviceContext)
 {
     if (!deviceContext)
         return E_POINTER;
@@ -5979,7 +6093,7 @@ HRESULT STDMETHODCALLTYPE WebView::elementFromJS(
 
     JSC::ExecState* exec = toJS(context);
     JSC::JSLockHolder lock(exec);
-    Element* elt = toElement(toJS(exec, nodeObject));
+    Element* elt = JSElement::toWrapped(toJS(exec, nodeObject));
     if (!elt)
         return E_FAIL;
 
@@ -5990,31 +6104,24 @@ HRESULT STDMETHODCALLTYPE WebView::elementFromJS(
 HRESULT STDMETHODCALLTYPE WebView::setCustomHTMLTokenizerTimeDelay(
     /* [in] */ double timeDelay)
 {
-    if (!m_page)
-        return E_FAIL;
-
-    m_page->setCustomHTMLTokenizerTimeDelay(timeDelay);
-    return S_OK;
+    ASSERT_NOT_REACHED();
+    return E_FAIL;
 }
 
 HRESULT STDMETHODCALLTYPE WebView::setCustomHTMLTokenizerChunkSize(
     /* [in] */ int chunkSize)
 {
-    if (!m_page)
-        return E_FAIL;
-
-    m_page->setCustomHTMLTokenizerChunkSize(chunkSize);
-    return S_OK;
+    ASSERT_NOT_REACHED();
+    return E_FAIL;
 }
 
-HRESULT STDMETHODCALLTYPE WebView::backingStore(
-    /* [out, retval] */ OLE_HANDLE* hBitmap)
+HRESULT WebView::backingStore(/* [out, retval] */ HBITMAP* hBitmap)
 {
     if (!hBitmap)
         return E_POINTER;
     if (!m_backingStoreBitmap)
         return E_FAIL;
-    *hBitmap = reinterpret_cast<OLE_HANDLE>(m_backingStoreBitmap->get());
+    *hBitmap = m_backingStoreBitmap->get();
     return S_OK;
 }
 
@@ -6211,13 +6318,13 @@ HRESULT STDMETHODCALLTYPE WebView::alwaysUsesComplexTextCodePath(BOOL* complex)
     return S_OK;
 }
 
-HRESULT STDMETHODCALLTYPE WebView::registerEmbeddedViewMIMEType(BSTR mimeType)
+HRESULT WebView::registerEmbeddedViewMIMEType(BSTR mimeType)
 {
     if (!mimeType)
         return E_POINTER;
 
     if (!m_embeddedViewMIMETypes)
-        m_embeddedViewMIMETypes = adoptPtr(new HashSet<String>);
+        m_embeddedViewMIMETypes = std::make_unique<HashSet<String>>();
 
     m_embeddedViewMIMETypes->add(toString(mimeType));
     return S_OK;
@@ -6228,6 +6335,9 @@ bool WebView::shouldUseEmbeddedView(const WTF::String& mimeType) const
     if (!m_embeddedViewMIMETypes)
         return false;
 
+    if (mimeType.isEmpty())
+        return false;
+
     return m_embeddedViewMIMETypes->contains(mimeType);
 }
 
@@ -6235,7 +6345,7 @@ bool WebView::onGetObject(WPARAM wParam, LPARAM lParam, LRESULT& lResult) const
 {
     lResult = 0;
 
-    if (lParam != OBJID_CLIENT)
+    if (static_cast<LONG>(lParam) != OBJID_CLIENT)
         return false;
 
     AXObjectCache::enableAccessibility();
@@ -6290,40 +6400,33 @@ HRESULT WebView::setCanStartPlugins(BOOL canStartPlugins)
     return S_OK;
 }
 
-void WebView::enterFullscreenForNode(Node* node)
+void WebView::enterVideoFullscreenForVideoElement(HTMLVideoElement& videoElement)
 {
-#if ENABLE(VIDEO)
-    if (!isHTMLVideoElement(node) || !node->isElementNode())
-        return;
-
-    if (!toElement(node)->isMediaElement())
-        return;
-    HTMLMediaElement* videoElement = toHTMLMediaElement(node);
-
+#if ENABLE(VIDEO) && !USE(GSTREAMER) && !USE(MEDIA_FOUNDATION)
     if (m_fullScreenVideoController) {
-        if (m_fullScreenVideoController->mediaElement() == videoElement) {
+        if (m_fullScreenVideoController->videoElement() == &videoElement) {
             // The backend may just warn us that the underlaying plaftormMovie()
             // has changed. Just force an update.
-            m_fullScreenVideoController->setMediaElement(videoElement);
+            m_fullScreenVideoController->setVideoElement(&videoElement);
             return; // No more to do.
         }
 
-        // First exit Fullscreen for the old mediaElement.
-        m_fullScreenVideoController->mediaElement()->exitFullscreen();
+        // First exit Fullscreen for the old videoElement.
+        m_fullScreenVideoController->videoElement()->exitFullscreen();
         // This previous call has to trigger exitFullscreen,
         // which has to clear m_fullScreenVideoController.
         ASSERT(!m_fullScreenVideoController);
     }
 
-    m_fullScreenVideoController = adoptPtr(new FullscreenVideoController);
-    m_fullScreenVideoController->setMediaElement(videoElement);
+    m_fullScreenVideoController = std::make_unique<FullscreenVideoController>();
+    m_fullScreenVideoController->setVideoElement(&videoElement);
     m_fullScreenVideoController->enterFullscreen();
 #endif
 }
 
-void WebView::exitFullscreen()
+void WebView::exitVideoFullscreenForVideoElement(WebCore::HTMLVideoElement&)
 {
-#if ENABLE(VIDEO)
+#if ENABLE(VIDEO) && !USE(GSTREAMER) && !USE(MEDIA_FOUNDATION)
     if (!m_fullScreenVideoController)
         return;
     
@@ -6332,157 +6435,44 @@ void WebView::exitFullscreen()
 #endif
 }
 
-static Vector<String> toStringVector(unsigned patternsCount, BSTR* patterns)
-{
-    Vector<String> patternsVector;
-    if (!patternsCount)
-        return patternsVector;
-    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), toURL(url),
-                                    toStringVector(whitelistCount, whitelist), toStringVector(blacklistCount, blacklist),
-                                    injectionTime == WebInjectAtDocumentStart ? InjectAtDocumentStart : InjectAtDocumentEnd,
-                                    InjectInAllFrames);
-
-    return S_OK;
+    return E_NOTIMPL;
 }
 
 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), toURL(url),
-                                        toStringVector(whitelistCount, whitelist), toStringVector(blacklistCount, blacklist),
-                                        InjectInAllFrames);
-
-    return S_OK;
+    return E_NOTIMPL;
 }
 
 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(), toURL(url));
-
-    return S_OK;
+    return E_NOTIMPL;
 }
 
 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(), toURL(url));
-
-    return S_OK;
+    return E_NOTIMPL;
 }
 
 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;
+    return E_NOTIMPL;
 }
 
 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;
+    return E_NOTIMPL;
 }
 
 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;
+    return E_NOTIMPL;
 }
 
 HRESULT WebView::invalidateBackingStore(const RECT* rect)
@@ -6506,13 +6496,13 @@ HRESULT WebView::invalidateBackingStore(const RECT* rect)
 
 HRESULT WebView::addOriginAccessWhitelistEntry(BSTR sourceOrigin, BSTR destinationProtocol, BSTR destinationHost, BOOL allowDestinationSubdomains)
 {
-    SecurityPolicy::addOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(toString(sourceOrigin)), toString(destinationProtocol), toString(destinationHost), allowDestinationSubdomains);
+    SecurityPolicy::addOriginAccessWhitelistEntry(SecurityOrigin::createFromString(toString(sourceOrigin)).get(), toString(destinationProtocol), toString(destinationHost), allowDestinationSubdomains);
     return S_OK;
 }
 
 HRESULT WebView::removeOriginAccessWhitelistEntry(BSTR sourceOrigin, BSTR destinationProtocol, BSTR destinationHost, BOOL allowDestinationSubdomains)
 {
-    SecurityPolicy::removeOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(toString(sourceOrigin)), toString(destinationProtocol), toString(destinationHost), allowDestinationSubdomains);
+    SecurityPolicy::removeOriginAccessWhitelistEntry(SecurityOrigin::createFromString(toString(sourceOrigin)).get(), toString(destinationProtocol), toString(destinationHost), allowDestinationSubdomains);
     return S_OK;
 }
 
@@ -6538,12 +6528,14 @@ HRESULT WebView::historyDelegate(IWebHistoryDelegate** historyDelegate)
 
 HRESULT WebView::addVisitedLinks(BSTR* visitedURLs, unsigned visitedURLCount)
 {
+    auto& visitedLinkStore = m_webViewGroup->visitedLinkStore();
     PageGroup& group = core(this)->group();
     
     for (unsigned i = 0; i < visitedURLCount; ++i) {
         BSTR url = visitedURLs[i];
         unsigned length = SysStringLen(url);
-        group.addVisitedLink(url, length);
+
+        visitedLinkStore.addVisitedLink(String(url, length));
     }
 
     return S_OK;
@@ -6551,19 +6543,34 @@ HRESULT WebView::addVisitedLinks(BSTR* visitedURLs, unsigned visitedURLCount)
 
 void WebView::downloadURL(const URL& url)
 {
+    if (!m_downloadDelegate)
+        return;
+
     // It's the delegate's job to ref the WebDownload to keep it alive - otherwise it will be
     // destroyed when this function returns.
+#if USE(CURL)
+    // For Curl we need to set the user agent, otherwise the download request gets the default Curl user agent string.
+    ResourceRequest request(url);
+    request.setHTTPUserAgent(userAgentForKURL(url));
+    COMPtr<WebDownload> download(AdoptCOM, WebDownload::createInstance(0, request, ResourceResponse(), m_downloadDelegate.get()));
+#else
     COMPtr<WebDownload> download(AdoptCOM, WebDownload::createInstance(url, m_downloadDelegate.get()));
+#endif
     download->start();
 }
 
-#if USE(ACCELERATED_COMPOSITING)
 void WebView::setRootChildLayer(GraphicsLayer* layer)
 {
     setAcceleratedCompositing(layer ? true : false);
+#if USE(CA)
     if (!m_backingLayer)
         return;
     m_backingLayer->addChild(layer);
+#elif USE(TEXTURE_MAPPER_GL)
+    if (!m_acceleratedCompositingContext)
+        return;
+    m_acceleratedCompositingContext->setRootCompositingLayer(layer);
+#endif
 }
 
 void WebView::flushPendingGraphicsLayerChangesSoon()
@@ -6572,13 +6579,20 @@ void WebView::flushPendingGraphicsLayerChangesSoon()
     if (!m_layerTreeHost)
         return;
     m_layerTreeHost->flushPendingGraphicsLayerChangesSoon();
+#elif USE(TEXTURE_MAPPER_GL)
+    if (!m_acceleratedCompositingContext)
+        return;
+    m_acceleratedCompositingContext->flushPendingLayerChangesSoon();
 #endif
 }
 
 void WebView::setAcceleratedCompositing(bool accelerated)
 {
+    if (m_isAcceleratedCompositing == accelerated)
+        return;
+
 #if USE(CA)
-    if (m_isAcceleratedCompositing == accelerated || !CACFLayerTreeHost::acceleratedCompositingAvailable())
+    if (!CACFLayerTreeHost::acceleratedCompositingAvailable())
         return;
 
     if (accelerated) {
@@ -6595,7 +6609,7 @@ void WebView::setAcceleratedCompositing(bool accelerated)
             // FIXME: We could perhaps get better performance by never allowing this layer to
             // become tiled (or choosing a higher-than-normal tiling threshold).
             // <http://webkit.org/b/52603>
-            m_backingLayer = GraphicsLayer::create(0, this);
+            m_backingLayer = GraphicsLayer::create(0, *this);
             m_backingLayer->setDrawsContent(true);
             m_backingLayer->setContentsOpaque(true);
             RECT clientRect;
@@ -6618,9 +6632,12 @@ void WebView::setAcceleratedCompositing(bool accelerated)
         m_backingLayer = nullptr;
         m_isAcceleratedCompositing = false;
     }
+#elif USE(TEXTURE_MAPPER_GL)
+    if (accelerated && !m_acceleratedCompositingContext)
+        m_acceleratedCompositingContext = std::make_unique<AcceleratedCompositingContext>(*this);
+    m_isAcceleratedCompositing = accelerated;
 #endif
 }
-#endif
 
 #if PLATFORM(WIN) && USE(AVFOUNDATION)
 WebCore::GraphicsDeviceAdapter* WebView::graphicsDeviceAdapter() const
@@ -6732,7 +6749,6 @@ HRESULT WebView::nextDisplayIsSynchronous()
     return S_OK;
 }
 
-#if USE(ACCELERATED_COMPOSITING)
 void WebView::notifyAnimationStarted(const GraphicsLayer*, double)
 {
     // We never set any animations on our backing layer.
@@ -6744,7 +6760,7 @@ void WebView::notifyFlushRequired(const GraphicsLayer*)
     flushPendingGraphicsLayerChangesSoon();
 }
 
-void WebView::paintContents(const GraphicsLayer*, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& inClip)
+void WebView::paintContents(const GraphicsLayer*, GraphicsContext& context, GraphicsLayerPaintingPhase, const FloatRect& inClip)
 {
     Frame* frame = core(m_mainFrame);
     if (!frame)
@@ -6752,7 +6768,7 @@ void WebView::paintContents(const GraphicsLayer*, GraphicsContext& context, Grap
 
     context.save();
     context.clip(inClip);
-    frame->view()->paint(&context, inClip);
+    frame->view()->paint(&context, enclosingIntRect(inClip));
     context.restore();
 }
 
@@ -6764,19 +6780,23 @@ void WebView::flushPendingGraphicsLayerChanges()
     FrameView* view = coreFrame->view();
     if (!view)
         return;
-    if (!m_backingLayer)
+
+    if (!isAcceleratedCompositing())
         return;
 
     view->updateLayoutAndStyleIfNeededRecursive();
 
+#if USE(CA)
     // Updating layout might have taken us out of compositing mode.
     if (m_backingLayer)
         m_backingLayer->flushCompositingStateForThisLayerOnly();
 
     view->flushCompositingStateIncludingSubframes();
-}
-
+#elif USE(TEXTURE_MAPPER_GL)
+    if (isAcceleratedCompositing())
+        m_acceleratedCompositingContext->flushPendingLayerChanges();
 #endif
+}
 
 class EnumTextMatches : public IEnumTextMatches
 {
@@ -6866,13 +6886,13 @@ HRESULT WebView::defaultMinimumTimerInterval(double* interval)
 {
     if (!interval)
         return E_POINTER;
-    *interval = Settings::defaultMinDOMTimerInterval();
+    *interval = DOMTimer::defaultMinimumInterval();
     return S_OK;
 }
 
 HRESULT WebView::setMinimumTimerInterval(double interval)
 {
-    page()->settings().setMinDOMTimerInterval(interval);
+    page()->settings().setMinimumDOMTimerInterval(interval);
     return S_OK;
 }
 
@@ -6916,7 +6936,7 @@ bool WebView::isFullScreen() const
 FullScreenController* WebView::fullScreenController()
 {
     if (!m_fullscreenController)
-        m_fullscreenController = adoptPtr(new FullScreenController(this));
+        m_fullscreenController = std::unique_ptr<FullScreenController>(new FullScreenController(this));
     return m_fullscreenController.get();
 }
 
@@ -6937,7 +6957,7 @@ HWND WebView::fullScreenClientParentWindow() const
 
 void WebView::fullScreenClientSetParentWindow(HWND hostWindow)
 {
-    setHostWindow(reinterpret_cast<OLE_HANDLE>(hostWindow));
+    setHostWindow(hostWindow);
 }
 
 void WebView::fullScreenClientWillEnterFullScreen()
@@ -7118,3 +7138,69 @@ HRESULT STDMETHODCALLTYPE WebView::selectedRangeForTesting(/* [out] */ UINT* loc
     return S_OK;
 }
 
+HRESULT WebView::setLoadResourcesSerially(BOOL serialize)
+{
+    WebPlatformStrategies::initialize();
+    resourceLoadScheduler()->setSerialLoadingEnabled(serialize);
+    return S_OK;
+}
+
+HRESULT WebView::scaleWebView(double scale, POINT origin)
+{
+    if (!m_page)
+        return E_FAIL;
+
+    m_page->setPageScaleFactor(scale, origin);
+
+    return S_OK;
+}
+
+HRESULT WebView::dispatchPendingLoadRequests()
+{
+    resourceLoadScheduler()->servePendingRequests();
+    return S_OK;
+}
+
+static float scaleFactorFromWindow(HWND window)
+{
+    HWndDC dc(window);
+    return ::GetDeviceCaps(dc, LOGPIXELSX) / 96.0f;
+}
+
+float WebView::deviceScaleFactor() const
+{
+    if (m_customDeviceScaleFactor)
+        return m_customDeviceScaleFactor;
+
+    // FIXME(146335): Should check for Windows 8.1 High DPI Features here first.
+
+    if (m_viewWindow)
+        return scaleFactorFromWindow(m_viewWindow);
+
+    if (m_hostWindow)
+        return scaleFactorFromWindow(m_hostWindow);
+
+    return scaleFactorFromWindow(0);
+}
+
+HRESULT WebView::setCustomBackingScaleFactor(double customScaleFactor)
+{
+    double oldScaleFactor = deviceScaleFactor();
+
+    m_customDeviceScaleFactor = customScaleFactor;
+
+    if (oldScaleFactor != deviceScaleFactor())
+        m_page->setDeviceScaleFactor(deviceScaleFactor());
+
+    return S_OK;
+}
+
+HRESULT WebView::backingScaleFactor(double* factor)
+{
+    if (!factor)
+        return E_POINTER;
+
+    *factor = deviceScaleFactor();
+
+    return S_OK;
+}