Title: [145332] trunk/Source
Revision
145332
Author
[email protected]
Date
2013-03-10 13:40:47 -0700 (Sun, 10 Mar 2013)

Log Message

Add a heuristic to determine the “primary” snapshotted plugin
https://bugs.webkit.org/show_bug.cgi?id=111932
<rdar://problem/13270208>

Reviewed by Dean Jackson.

* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchDidCommitLoad):
Forward didCommitLoad to WebPage. Move existing code that manipulated WebPage
itself during didCommitLoad into WebPage, where it belongs.
(WebKit::WebFrameLoaderClient::dispatchDidFinishLoad): Forward didFinishLoad to WebPage.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::WebPage): Initialize m_didFindPrimarySnapshottedPlugin to false.
(WebKit::WebPage::didCommitLoad): Move code from WebPageFrameLoaderClient.
Reset the flag that says we've already found a snapshotted plugin.
(WebKit::WebPage::didFinishLoad):
Call determinePrimarySnapshottedPlugIn when any frame finishes loading. We call this for subframes,
not just the main frame, in case the main frame loads with no "primary" plugins, but a subframe later loads with one.
(WebKit::WebPage::determinePrimarySnapshottedPlugIn):
Attempt to find the primary snapshotted plugin on the page, by hit-testing a grid of points spaced 200px apart.
A plugin is considered if it is snapshotted and > 450x300. We scan vertically and left-to-right, only discarding
a previous candidate if another candidate is at least 110% the size of the previous candidate.
This tends to select plugins near the top left of the page, unless there is a significantly larger plugin elsewhere.
(WebKit::WebPage::resetPrimarySnapshottedPlugIn):
* WebProcess/WebPage/WebPage.h:
(WebPage):

* WebCore.exp.in: Export a few things.
* html/HTMLPlugInImageElement.cpp:
(WebCore::HTMLPlugInImageElement::HTMLPlugInImageElement):
(WebCore::classNameForShadowRoot): If we've been informed that we are the primary snapshotted plugin, add the 'primary' class.
(WebCore::HTMLPlugInImageElement::setIsPrimarySnapshottedPlugIn): Added
(WebCore::HTMLPlugInImageElement::updateSnapshotInfo): Hand classNameForShadowRoot our primary-ness.
* html/HTMLPlugInImageElement.h:
(HTMLPlugInImageElement): Add storage for m_isPrimarySnapshottedPlugIn.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (145331 => 145332)


--- trunk/Source/WebCore/ChangeLog	2013-03-10 19:57:08 UTC (rev 145331)
+++ trunk/Source/WebCore/ChangeLog	2013-03-10 20:40:47 UTC (rev 145332)
@@ -1,3 +1,20 @@
+2013-03-10  Tim Horton  <[email protected]>
+
+        Add a heuristic to determine the “primary” snapshotted plugin
+        https://bugs.webkit.org/show_bug.cgi?id=111932
+        <rdar://problem/13270208>
+
+        Reviewed by Dean Jackson.
+
+        * WebCore.exp.in: Export a few things.
+        * html/HTMLPlugInImageElement.cpp:
+        (WebCore::HTMLPlugInImageElement::HTMLPlugInImageElement):
+        (WebCore::classNameForShadowRoot): If we've been informed that we are the primary snapshotted plugin, add the 'primary' class.
+        (WebCore::HTMLPlugInImageElement::setIsPrimarySnapshottedPlugIn): Added
+        (WebCore::HTMLPlugInImageElement::updateSnapshotInfo): Hand classNameForShadowRoot our primary-ness.
+        * html/HTMLPlugInImageElement.h:
+        (HTMLPlugInImageElement): Add storage for m_isPrimarySnapshottedPlugIn.
+
 2013-03-10  Mike West  <[email protected]>
 
         XSSAuditor doesn't need a copy of the original document URL.

Modified: trunk/Source/WebCore/WebCore.exp.in (145331 => 145332)


--- trunk/Source/WebCore/WebCore.exp.in	2013-03-10 19:57:08 UTC (rev 145331)
+++ trunk/Source/WebCore/WebCore.exp.in	2013-03-10 20:40:47 UTC (rev 145332)
@@ -76,6 +76,7 @@
 __ZN7WebCore10MouseEvent6createERKN3WTF12AtomicStringEbbNS1_10PassRefPtrINS_9DOMWindowEEEiiiiibbbbtNS5_INS_11EventTargetEEENS5_INS_9ClipboardEEEb
 __ZN7WebCore10MouseEventC1ERKN3WTF12AtomicStringEbbNS1_10PassRefPtrINS_9DOMWindowEEEiiiiibbbbtNS5_INS_11EventTargetEEENS5_INS_9ClipboardEEEb
 __ZN7WebCore10RenderView10compositorEv
+__ZN7WebCore10RenderView7hitTestERKNS_14HitTestRequestERNS_13HitTestResultE
 __ZN7WebCore10ScrollView17setUseFixedLayoutEb
 __ZN7WebCore10ScrollView18setFixedLayoutSizeERKNS_7IntSizeE
 __ZN7WebCore10ScrollView20setCanHaveScrollbarsEb
@@ -248,6 +249,7 @@
 __ZN7WebCore13HTTPHeaderMapC1Ev
 __ZN7WebCore13HTTPHeaderMapD1Ev
 __ZN7WebCore13HitTestResultC1ERKS0_
+__ZN7WebCore13HitTestResultC1ERKNS_11LayoutPointE
 __ZN7WebCore13HitTestResultD1Ev
 __ZN7WebCore13IdentifierRep3getEPKc
 __ZN7WebCore13IdentifierRep3getEi
@@ -673,6 +675,7 @@
 __ZN7WebCore22externalRepresentationEPNS_7ElementEj
 __ZN7WebCore22systemMarketingVersionEv
 __ZN7WebCore22userPreferredLanguagesEv
+__ZN7WebCore22HTMLPlugInImageElement29setIsPrimarySnapshottedPlugInEb
 __ZN7WebCore23ApplicationCacheStorage14setMaximumSizeEx
 __ZN7WebCore23ApplicationCacheStorage16deleteAllEntriesEv
 __ZN7WebCore23ApplicationCacheStorage16storeCopyOfCacheERKN3WTF6StringEPNS_20ApplicationCacheHostE
@@ -1254,6 +1257,7 @@
 __ZNK7WebCore13HitTestResult10isSelectedEv
 __ZNK7WebCore13HitTestResult11targetFrameEv
 __ZNK7WebCore13HitTestResult11textContentEv
+__ZNK7WebCore13HitTestResult12innerElementEv
 __ZNK7WebCore13HitTestResult14absolutePDFURLEv
 __ZNK7WebCore13HitTestResult14innerNodeFrameEv
 __ZNK7WebCore13HitTestResult15absoluteLinkURLEv
@@ -1431,6 +1435,7 @@
 __ZNK7WebCore4Node9nodeIndexEv
 __ZNK7WebCore4Page10pluginDataEv
 __ZNK7WebCore4Page14renderTreeSizeEv
+__ZNK7WebCore4Page16hasSeenAnyPluginEv
 __ZNK7WebCore4Page15backForwardListEv
 __ZNK7WebCore4Page17viewportArgumentsEv
 __ZNK7WebCore4Page34inLowQualityImageInterpolationModeEv
@@ -1547,6 +1552,8 @@
 __ZNK7WebCore9FrameView34setWantsLayerForBottomOverHangAreaEb
 #endif
 __ZNK7WebCore9PageCache10frameCountEv
+__ZNK7WebCore9RenderBox12clientHeightEv
+__ZNK7WebCore9RenderBox11clientWidthEv
 __ZTVN7WebCore12ChromeClientE
 __ZTVN7WebCore14LoaderStrategyE
 __ZTVN7WebCore15StorageStrategyE

Modified: trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp (145331 => 145332)


--- trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp	2013-03-10 19:57:08 UTC (rev 145331)
+++ trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp	2013-03-10 20:40:47 UTC (rev 145332)
@@ -71,6 +71,7 @@
     , m_needsWidgetUpdate(!createdByParser)
     , m_shouldPreferPlugInsForImages(preferPlugInsForImagesOption == ShouldPreferPlugInsForImages)
     , m_needsDocumentActivationCallbacks(false)
+    , m_isPrimarySnapshottedPlugIn(false)
     , m_simulatedMouseClickTimer(this, &HTMLPlugInImageElement::simulatedMouseClickTimerFired, simulatedMouseClickTimerDelay)
     , m_swapRendererTimer(this, &HTMLPlugInImageElement::swapRendererTimerFired)
 {
@@ -295,12 +296,13 @@
         renderer()->repaint();
 }
 
-static AtomicString classNameForShadowRoot(const Node* node)
+static AtomicString classNameForShadowRoot(const Node* node, bool isPrimary)
 {
     DEFINE_STATIC_LOCAL(const AtomicString, plugInTinySizeClassName, ("tiny", AtomicString::ConstructFromLiteral));
     DEFINE_STATIC_LOCAL(const AtomicString, plugInSmallSizeClassName, ("small", AtomicString::ConstructFromLiteral));
     DEFINE_STATIC_LOCAL(const AtomicString, plugInMediumSizeClassName, ("medium", AtomicString::ConstructFromLiteral));
     DEFINE_STATIC_LOCAL(const AtomicString, plugInLargeSizeClassName, ("large", AtomicString::ConstructFromLiteral));
+    DEFINE_STATIC_LOCAL(const AtomicString, plugInLargeSizePrimaryClassName, ("large primary", AtomicString::ConstructFromLiteral));
 
     RenderBox* renderBox = static_cast<RenderBox*>(node->renderer());
     LayoutUnit width = renderBox->contentWidth();
@@ -315,8 +317,15 @@
     if (width < sizingMediumWidthThreshold || height < sizingMediumHeightThreshold)
         return plugInMediumSizeClassName;
 
-    return plugInLargeSizeClassName;
+    return isPrimary ? plugInLargeSizePrimaryClassName : plugInLargeSizeClassName;
 }
+    
+void HTMLPlugInImageElement::setIsPrimarySnapshottedPlugIn(bool isPrimarySnapshottedPlugIn)
+{
+    m_isPrimarySnapshottedPlugIn = isPrimarySnapshottedPlugIn;
+    
+    updateSnapshotInfo();
+}
 
 void HTMLPlugInImageElement::updateSnapshotInfo()
 {
@@ -325,7 +334,7 @@
         return;
 
     Element* shadowContainer = static_cast<Element*>(root->firstChild());
-    shadowContainer->setAttribute(classAttr, classNameForShadowRoot(this));
+    shadowContainer->setAttribute(classAttr, classNameForShadowRoot(this, m_isPrimarySnapshottedPlugIn));
 }
 
 void HTMLPlugInImageElement::didAddUserAgentShadowRoot(ShadowRoot* root)

Modified: trunk/Source/WebCore/html/HTMLPlugInImageElement.h (145331 => 145332)


--- trunk/Source/WebCore/html/HTMLPlugInImageElement.h	2013-03-10 19:57:08 UTC (rev 145331)
+++ trunk/Source/WebCore/html/HTMLPlugInImageElement.h	2013-03-10 20:40:47 UTC (rev 145332)
@@ -71,6 +71,8 @@
     // Plug-in URL might not be the same as url() with overriding parameters.
     void subframeLoaderWillCreatePlugIn(const KURL& plugInURL);
     void subframeLoaderDidCreatePlugIn(const Widget*);
+    
+    void setIsPrimarySnapshottedPlugIn(bool);
 
 protected:
     HTMLPlugInImageElement(const QualifiedName& tagName, Document*, bool createdByParser, PreferPlugInsForImagesOption);
@@ -117,6 +119,7 @@
     bool m_needsWidgetUpdate;
     bool m_shouldPreferPlugInsForImages;
     bool m_needsDocumentActivationCallbacks;
+    bool m_isPrimarySnapshottedPlugIn;
     RefPtr<RenderStyle> m_customStyleForPageCache;
     RefPtr<MouseEvent> m_pendingClickEventFromSnapshot;
     DeferrableOneShotTimer<HTMLPlugInImageElement> m_simulatedMouseClickTimer;

Modified: trunk/Source/WebKit2/ChangeLog (145331 => 145332)


--- trunk/Source/WebKit2/ChangeLog	2013-03-10 19:57:08 UTC (rev 145331)
+++ trunk/Source/WebKit2/ChangeLog	2013-03-10 20:40:47 UTC (rev 145332)
@@ -1,3 +1,32 @@
+2013-03-10  Tim Horton  <[email protected]>
+
+        Add a heuristic to determine the “primary” snapshotted plugin
+        https://bugs.webkit.org/show_bug.cgi?id=111932
+        <rdar://problem/13270208>
+
+        Reviewed by Dean Jackson.
+
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::dispatchDidCommitLoad):
+        Forward didCommitLoad to WebPage. Move existing code that manipulated WebPage
+        itself during didCommitLoad into WebPage, where it belongs.
+        (WebKit::WebFrameLoaderClient::dispatchDidFinishLoad): Forward didFinishLoad to WebPage.
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::WebPage): Initialize m_didFindPrimarySnapshottedPlugin to false.
+        (WebKit::WebPage::didCommitLoad): Move code from WebPageFrameLoaderClient.
+        Reset the flag that says we've already found a snapshotted plugin.
+        (WebKit::WebPage::didFinishLoad):
+        Call determinePrimarySnapshottedPlugIn when any frame finishes loading. We call this for subframes,
+        not just the main frame, in case the main frame loads with no "primary" plugins, but a subframe later loads with one.
+        (WebKit::WebPage::determinePrimarySnapshottedPlugIn):
+        Attempt to find the primary snapshotted plugin on the page, by hit-testing a grid of points spaced 200px apart.
+        A plugin is considered if it is snapshotted and > 450x300. We scan vertically and left-to-right, only discarding
+        a previous candidate if another candidate is at least 110% the size of the previous candidate.
+        This tends to select plugins near the top left of the page, unless there is a significantly larger plugin elsewhere.
+        (WebKit::WebPage::resetPrimarySnapshottedPlugIn):
+        * WebProcess/WebPage/WebPage.h:
+        (WebPage):
+
 2013-03-10  Sheriff Bot  <[email protected]>
 
         Unreviewed, rolling out r145039 and r145096.

Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (145331 => 145332)


--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp	2013-03-10 19:57:08 UTC (rev 145331)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp	2013-03-10 20:40:47 UTC (rev 145332)
@@ -444,12 +444,7 @@
 
     webPage->send(Messages::WebPageProxy::DidCommitLoadForFrame(m_frame->frameID(), response.mimeType(), m_frameHasCustomRepresentation, m_frame->coreFrame()->loader()->loadType(), PlatformCertificateInfo(response), InjectedBundleUserMessageEncoder(userData.get())));
 
-    // Only restore the scale factor for standard frame loads (of the main frame).
-    if (m_frame->isMainFrame() && m_frame->coreFrame()->loader()->loadType() == FrameLoadTypeStandard) {
-        Page* page = m_frame->coreFrame()->page();
-        if (page && page->pageScaleFactor() != 1)
-            webPage->scalePage(1, IntPoint());
-    }
+    webPage->didCommitLoad(m_frame);
 }
 
 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
@@ -524,6 +519,8 @@
     // If we have a load listener, notify it.
     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
         loadListener->didFinishLoad(m_frame);
+
+    webPage->didFinishLoad(m_frame);
 }
 
 void WebFrameLoaderClient::dispatchDidLayout(LayoutMilestones milestones)

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (145331 => 145332)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp	2013-03-10 19:57:08 UTC (rev 145331)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp	2013-03-10 20:40:47 UTC (rev 145332)
@@ -101,6 +101,7 @@
 #include <WebCore/HTMLFormElement.h>
 #include <WebCore/HTMLInputElement.h>
 #include <WebCore/HTMLPlugInElement.h>
+#include <WebCore/HTMLPlugInImageElement.h>
 #include <WebCore/HistoryItem.h>
 #include <WebCore/KeyboardEvent.h>
 #include <WebCore/MIMETypeRegistry.h>
@@ -235,6 +236,9 @@
     , m_artificialPluginInitializationDelayEnabled(false)
     , m_scrollingPerformanceLoggingEnabled(false)
     , m_mainFrameIsScrollable(true)
+#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
+    , m_didFindPrimarySnapshottedPlugin(false)
+#endif
 #if PLATFORM(MAC)
     , m_pdfPluginEnabled(false)
     , m_hasCachedWindowFrame(false)
@@ -3864,4 +3868,109 @@
     m_pendingTextCheckingRequestMap.remove(requestID);
 }
 
+void WebPage::didCommitLoad(WebFrame* frame)
+{
+    // Only restore the scale factor for standard frame loads (of the main frame).
+    if (frame->isMainFrame() && frame->coreFrame()->loader()->loadType() == FrameLoadTypeStandard) {
+        Page* page = frame->coreFrame()->page();
+        if (page && page->pageScaleFactor() != 1)
+            scalePage(1, IntPoint());
+    }
+
+#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
+    if (frame->isMainFrame())
+        resetPrimarySnapshottedPlugIn();
+#endif
+}
+
+void WebPage::didFinishLoad(WebFrame* frame)
+{
+#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
+    determinePrimarySnapshottedPlugIn();
+#endif
+}
+
+#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
+static int primarySnapshottedPlugInSearchLimit = 3000;
+static int primarySnapshottedPlugInSearchGap = 200;
+static float primarySnapshottedPlugInSearchBucketSize = 1.1;
+static int primarySnapshottedPlugInMinimumWidth = 450;
+static int primarySnapshottedPlugInMinimumHeight = 300;
+
+void WebPage::determinePrimarySnapshottedPlugIn()
+{
+    if (!corePage()->hasSeenAnyPlugin())
+        return;
+
+    if (m_didFindPrimarySnapshottedPlugin)
+        return;
+
+    RenderView* renderView = corePage()->mainFrame()->view()->renderView();
+
+    IntRect searchRect = IntRect(IntPoint(), corePage()->mainFrame()->view()->contentsSize());
+    searchRect.intersect(IntRect(IntPoint(), IntSize(primarySnapshottedPlugInSearchLimit, primarySnapshottedPlugInSearchLimit)));
+
+    HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent | HitTestRequest::IgnoreClipping);
+
+    HashSet<RenderObject*> seenRenderers;
+    HTMLPlugInImageElement* candidatePlugIn = 0;
+    unsigned candidatePlugInArea = 0;
+
+    for (int x = searchRect.x(); x <= searchRect.width(); x += primarySnapshottedPlugInSearchGap) {
+        for (int y = searchRect.y(); y <= searchRect.height(); y += primarySnapshottedPlugInSearchGap) {
+            HitTestResult hitTestResult = HitTestResult(LayoutPoint(x, y));
+            renderView->hitTest(request, hitTestResult);
+
+            Element* element = hitTestResult.innerElement();
+            if (!element)
+                continue;
+
+            RenderObject* renderer = element->renderer();
+            if (!renderer || !renderer->isBox())
+                continue;
+
+            RenderBox* renderBox = toRenderBox(renderer);
+
+            if (seenRenderers.contains(renderer))
+                continue;
+            seenRenderers.add(renderer);
+
+            if (!element->isPluginElement())
+                continue;
+
+            HTMLPlugInElement* plugInElement = toHTMLPlugInElement(element);
+            if (!plugInElement->isPlugInImageElement())
+                continue;
+
+            HTMLPlugInImageElement* plugInImageElement = toHTMLPlugInImageElement(plugInElement);
+
+            if (plugInElement->displayState() == HTMLPlugInElement::Playing)
+                continue;
+
+            if (renderBox->contentWidth() < primarySnapshottedPlugInMinimumWidth || renderBox->contentHeight() < primarySnapshottedPlugInMinimumHeight)
+                continue;
+
+            LayoutUnit contentArea = renderBox->contentWidth() * renderBox->contentHeight();
+
+            if (contentArea > candidatePlugInArea * primarySnapshottedPlugInSearchBucketSize) {
+                candidatePlugIn = plugInImageElement;
+                candidatePlugInArea = contentArea;
+            }
+        }
+    }
+
+    if (!candidatePlugIn)
+        return;
+
+    m_didFindPrimarySnapshottedPlugin = true;
+
+    candidatePlugIn->setIsPrimarySnapshottedPlugIn(true);
+}
+
+void WebPage::resetPrimarySnapshottedPlugIn()
+{
+    m_didFindPrimarySnapshottedPlugin = false;
+}
+#endif // ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
+
 } // namespace WebKit

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (145331 => 145332)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2013-03-10 19:57:08 UTC (rev 145331)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2013-03-10 20:40:47 UTC (rev 145332)
@@ -98,6 +98,8 @@
 OBJC_CLASS NSDictionary;
 OBJC_CLASS NSObject;
 OBJC_CLASS WKAccessibilityWebPageObject;
+
+#define WTF_ENABLE_PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC 1
 #endif
 
 namespace CoreIPC {
@@ -217,6 +219,8 @@
 
     void didStartPageTransition();
     void didCompletePageTransition();
+    void didCommitLoad(WebFrame*);
+    void didFinishLoad(WebFrame*);
     void show();
     String userAgent() const { return m_userAgent; }
     WebCore::IntRect windowResizerRect() const;
@@ -630,6 +634,11 @@
     void didFinishCheckingText(uint64_t requestID, const Vector<WebCore::TextCheckingResult>&);
     void didCancelCheckingText(uint64_t requestID);
 
+#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
+    void determinePrimarySnapshottedPlugIn();
+    void resetPrimarySnapshottedPlugIn();
+#endif
+
 private:
     WebPage(uint64_t pageID, const WebPageCreationParameters&);
 
@@ -844,6 +853,10 @@
 
     bool m_mainFrameIsScrollable;
 
+#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
+    bool m_didFindPrimarySnapshottedPlugin;
+#endif
+
 #if PLATFORM(MAC)
     bool m_pdfPluginEnabled;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to