Changeset 145421 in webkit


Ignore:
Timestamp:
Mar 11, 2013 3:51:43 PM (11 years ago)
Author:
dino@apple.com
Message:

Plugins created during user gestures (or soon after) should not be snapshotted
https://bugs.webkit.org/show_bug.cgi?id=111975

Reviewed by Tim Horton.

There are sites which create plugins in response to user actions, such as clicking
on an image that is acting like a poster frame. In those cases we should never snapshot.

There are some other sites which also create plugins in response to user actions,
but don't necessarily create the content themselves. Instead they run some script
that injects an iframe, and the frame loads a plugin. In order to make sure we don't
snapshot in those cases, we're adding the concept of a blessed plugin. Anything that
is created soon after a *handled* user gesture is not snapshotted. To do this we
mark a timestamp in the document when we've called an event listener for a user
gesture. The plugin element then compares its creation time with the most recent
user action time.

  • dom/Document.cpp:

(WebCore::Document::Document): Initialise new timestamp.
(WebCore::Document::resetLastHandledUserGestureTimestamp): Sets the member variable

to the current time.

  • dom/Document.h:

(WebCore::Document::lastHandledUserGestureTimestamp): Getter.

  • dom/EventTarget.cpp:

(WebCore::EventTarget::fireEventListeners): If there were some event listeners and

we were processing a user gesture, then reset the timestamp in the document.

  • html/HTMLPlugInImageElement.cpp:

(WebCore::HTMLPlugInImageElement::HTMLPlugInImageElement): Remember if we were created

during a user gesture.

(WebCore::HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn): Start the plugin

if we were created during a user gesture, or if we are close enough in time
to a listener that fired in relation to a user gesture.

  • html/HTMLPlugInImageElement.h: New private member flag indicating if we were

in a user gesture when constructed.

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r145419 r145421  
     12013-03-11  Dean Jackson  <dino@apple.com>
     2
     3        Plugins created during user gestures (or soon after) should not be snapshotted
     4        https://bugs.webkit.org/show_bug.cgi?id=111975
     5
     6        Reviewed by Tim Horton.
     7
     8        There are sites which create plugins in response to user actions, such as clicking
     9        on an image that is acting like a poster frame. In those cases we should never snapshot.
     10
     11        There are some other sites which also create plugins in response to user actions,
     12        but don't necessarily create the content themselves. Instead they run some script
     13        that injects an iframe, and the frame loads a plugin. In order to make sure we don't
     14        snapshot in those cases, we're adding the concept of a blessed plugin. Anything that
     15        is created soon after a *handled* user gesture is not snapshotted. To do this we
     16        mark a timestamp in the document when we've called an event listener for a user
     17        gesture. The plugin element then compares its creation time with the most recent
     18        user action time.
     19
     20        * dom/Document.cpp:
     21        (WebCore::Document::Document): Initialise new timestamp.
     22        (WebCore::Document::resetLastHandledUserGestureTimestamp): Sets the member variable
     23            to the current time.
     24        * dom/Document.h:
     25        (WebCore::Document::lastHandledUserGestureTimestamp): Getter.
     26
     27        * dom/EventTarget.cpp:
     28        (WebCore::EventTarget::fireEventListeners): If there were some event listeners and
     29            we were processing a user gesture, then reset the timestamp in the document.
     30
     31        * html/HTMLPlugInImageElement.cpp:
     32        (WebCore::HTMLPlugInImageElement::HTMLPlugInImageElement): Remember if we were created
     33            during a user gesture.
     34        (WebCore::HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn): Start the plugin
     35            if we were created during a user gesture, or if we are close enough in time
     36            to a listener that fired in relation to a user gesture.
     37        * html/HTMLPlugInImageElement.h: New private member flag indicating if we were
     38            in a user gesture when constructed.
     39
    1402013-03-11  Jeffrey Pfau  <jpfau@apple.com>
    241
  • trunk/Source/WebCore/dom/Document.cpp

    r145342 r145421  
    477477    , m_writeRecursionDepth(0)
    478478    , m_wheelEventHandlerCount(0)
     479    , m_lastHandledUserGestureTimestamp(0)
    479480    , m_pendingTasksTimer(this, &Document::pendingTasksTimerFired)
    480481    , m_scheduledTasksAreSuspended(false)
     
    56785679#endif
    56795680
     5681void Document::resetLastHandledUserGestureTimestamp()
     5682{
     5683    m_lastHandledUserGestureTimestamp = currentTime();
     5684}
     5685
    56805686HTMLIFrameElement* Document::seamlessParentIFrame() const
    56815687{
  • trunk/Source/WebCore/dom/Document.h

    r145340 r145421  
    11021102    void didRemoveWheelEventHandler();
    11031103
     1104    double lastHandledUserGestureTimestamp() const { return m_lastHandledUserGestureTimestamp; }
     1105    void resetLastHandledUserGestureTimestamp();
     1106
    11041107#if ENABLE(TOUCH_EVENTS)
    11051108    bool hasTouchEventHandlers() const { return (m_touchEventTargets.get()) ? m_touchEventTargets->size() : false; }
     
    15141517#endif
    15151518
     1519    double m_lastHandledUserGestureTimestamp;
     1520
    15161521#if ENABLE(REQUEST_ANIMATION_FRAME)
    15171522    RefPtr<ScriptedAnimationController> m_scriptedAnimationController;
  • trunk/Source/WebCore/dom/EventTarget.cpp

    r141119 r145421  
    233233    // so iterating to 'end' naturally excludes new event listeners.
    234234
     235    bool userEventWasHandled = false;
    235236    size_t i = 0;
    236237    size_t end = entry.size();
     
    255256        // event listeners, even though that violates some versions of the DOM spec.
    256257        registeredListener.listener->handleEvent(context, event);
     258        if (!userEventWasHandled && ScriptController::processingUserGesture())
     259            userEventWasHandled = true;
    257260        InspectorInstrumentation::didHandleEvent(cookie);
    258261    }
    259262    d->firingEventIterators->removeLast();
     263    if (userEventWasHandled) {
     264        ScriptExecutionContext* context = scriptExecutionContext();
     265        if (context && context->isDocument()) {
     266            Document* document = static_cast<Document*>(context);
     267            document->resetLastHandledUserGestureTimestamp();
     268        }
     269    }
    260270}
    261271
  • trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp

    r145332 r145421  
    5959static const int sizingMediumHeightThreshold = 300;
    6060static const float sizingFullPageAreaRatioThreshold = 0.96;
     61static const float autostartSoonAfterUserGestureThreshold = 5.0;
    6162
    6263// This delay should not exceed the snapshot delay in PluginView.cpp
     
    7576    , m_simulatedMouseClickTimer(this, &HTMLPlugInImageElement::simulatedMouseClickTimerFired, simulatedMouseClickTimerDelay)
    7677    , m_swapRendererTimer(this, &HTMLPlugInImageElement::swapRendererTimerFired)
     78    , m_createdDuringUserGesture(ScriptController::processingUserGesture())
    7779{
    7880    setHasCustomStyleCallbacks();
     
    445447    }
    446448
     449    if (m_createdDuringUserGesture) {
     450        LOG(Plugins, "%p Plug-in was created when processing user gesture, set to play", this);
     451        return;
     452    }
     453
     454    double lastKnownUserGestureTimestamp = document()->lastHandledUserGestureTimestamp();
     455    if (!inMainFrame && document()->page()->mainFrame() && document()->page()->mainFrame()->document())
     456        lastKnownUserGestureTimestamp = std::max(lastKnownUserGestureTimestamp, document()->page()->mainFrame()->document()->lastHandledUserGestureTimestamp());
     457    if (currentTime() - lastKnownUserGestureTimestamp < autostartSoonAfterUserGestureThreshold) {
     458        LOG(Plugins, "%p Plug-in was created shortly after a user gesture, set to play", this);
     459        return;
     460    }
     461
    447462    RenderBox* renderEmbeddedObject = toRenderBox(renderer());
    448463    Length styleWidth = renderEmbeddedObject->style()->width();
  • trunk/Source/WebCore/html/HTMLPlugInImageElement.h

    r145332 r145421  
    126126    Timer<HTMLPlugInImageElement> m_swapRendererTimer;
    127127    RefPtr<Image> m_snapshotImage;
     128    bool m_createdDuringUserGesture;
    128129};
    129130
Note: See TracChangeset for help on using the changeset viewer.