Changeset 142685 in webkit


Ignore:
Timestamp:
Feb 12, 2013 3:53:15 PM (11 years ago)
Author:
dino@apple.com
Message:

Add class name for snapshotted plugin based on dimensions
https://bugs.webkit.org/show_bug.cgi?id=108369

Reviewed by Simon Fraser.

As the size of the plugin changes, the Shadow Root for the snapshot
might want to toggle different interfaces. Expose "tiny", "small",
"medium" and "large" classes on the Shadow. (The dimensions are
currently chosen fairly arbitrarily).

Because we only know the dimensions after layout, we set up
a post layout task to add the class. Luckily there already was
a post layout task for plugins - I just updated it to handle
both real and snapshotted plugins. This involved modifying
the list of RenderEmbeddedObjects in FrameView to take generic
RenderObjects, and decide which type they are when calling
the update method.

  • html/HTMLPlugInImageElement.cpp: Some new dimensions for the various size thresholds.

(WebCore::classNameForShadowRootSize): New static function that returns a class name

after examining the size of the object.

(WebCore::HTMLPlugInImageElement::updateSnapshotInfo): Sets the class name for

the shadow root. This is called in the post layout task.

(WebCore::shouldPlugInShowLabelAutomatically): Use new size names.
(WebCore::HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn): Ditto.

  • html/HTMLPlugInImageElement.h:

(HTMLPlugInImageElement): New method updateSnapshotInfo.

  • page/FrameView.cpp:

(WebCore::FrameView::addWidgetToUpdate): Change RenderEmbeddedObject* to RenderObject*.
(WebCore::FrameView::removeWidgetToUpdate): Ditto
(WebCore::FrameView::updateWidget): Branch based on EmbeddedObject vs SnapshottedPlugIn. Call

plugin snapshot update if necessary.

(WebCore::FrameView::updateWidgets): Handle both EmbeddedObject and SnapshottedPlugIn cases.

  • page/FrameView.h: Change RenderEmbeddedObject* to RenderObject* for post layout widget updates.
  • rendering/RenderSnapshottedPlugIn.cpp:

(WebCore::RenderSnapshottedPlugIn::layout): New virtual override. If size has changed, ask the

FrameView to recalculate size after layout.

  • rendering/RenderSnapshottedPlugIn.h: New layout() method.
Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r142683 r142685  
     12013-02-12  Dean Jackson  <dino@apple.com>
     2
     3        Add class name for snapshotted plugin based on dimensions
     4        https://bugs.webkit.org/show_bug.cgi?id=108369
     5
     6        Reviewed by Simon Fraser.
     7
     8        As the size of the plugin changes, the Shadow Root for the snapshot
     9        might want to toggle different interfaces. Expose "tiny", "small",
     10        "medium" and "large" classes on the Shadow. (The dimensions are
     11        currently chosen fairly arbitrarily).
     12
     13        Because we only know the dimensions after layout, we set up
     14        a post layout task to add the class. Luckily there already was
     15        a post layout task for plugins - I just updated it to handle
     16        both real and snapshotted plugins. This involved modifying
     17        the list of RenderEmbeddedObjects in FrameView to take generic
     18        RenderObjects, and decide which type they are when calling
     19        the update method.
     20
     21        * html/HTMLPlugInImageElement.cpp: Some new dimensions for the various size thresholds.
     22        (WebCore::classNameForShadowRootSize): New static function that returns a class name
     23            after examining the size of the object.
     24        (WebCore::HTMLPlugInImageElement::updateSnapshotInfo): Sets the class name for
     25            the shadow root. This is called in the post layout task.
     26        (WebCore::shouldPlugInShowLabelAutomatically): Use new size names.
     27        (WebCore::HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn): Ditto.
     28        * html/HTMLPlugInImageElement.h:
     29        (HTMLPlugInImageElement): New method updateSnapshotInfo.
     30
     31        * page/FrameView.cpp:
     32        (WebCore::FrameView::addWidgetToUpdate): Change RenderEmbeddedObject* to RenderObject*.
     33        (WebCore::FrameView::removeWidgetToUpdate): Ditto
     34        (WebCore::FrameView::updateWidget): Branch based on EmbeddedObject vs SnapshottedPlugIn. Call
     35            plugin snapshot update if necessary.
     36        (WebCore::FrameView::updateWidgets): Handle both EmbeddedObject and SnapshottedPlugIn cases.
     37        * page/FrameView.h: Change RenderEmbeddedObject* to RenderObject* for post layout widget updates.
     38
     39        * rendering/RenderSnapshottedPlugIn.cpp:
     40        (WebCore::RenderSnapshottedPlugIn::layout): New virtual override. If size has changed, ask the
     41            FrameView to recalculate size after layout.
     42        * rendering/RenderSnapshottedPlugIn.h: New layout() method.
     43
    1442013-02-12  Mike West  <mkwst@chromium.org>
    245
  • trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp

    r142507 r142685  
    5454using namespace HTMLNames;
    5555
    56 static const int autoStartPlugInSizeThresholdWidth = 1;
    57 static const int autoStartPlugInSizeThresholdHeight = 1;
    58 static const int autoShowLabelSizeThresholdWidth = 400;
    59 static const int autoShowLabelSizeThresholdHeight = 300;
     56static const int autoStartPlugInSizeDimensionThreshold = 1;
     57static const int autoShowLabelSizeWidthThreshold = 400;
     58static const int autoShowLabelSizeHeightThreshold = 300;
     59
     60static const int sizingTinyDimensionThreshold = 40;
     61static const int sizingSmallWidthThreshold = 250;
     62static const int sizingMediumWidthThreshold = 600;
     63
    6064// This delay should not exceed the snapshot delay in PluginView.cpp
    6165static const double simulatedMouseClickTimerDelay = .75;
     
    289293}
    290294
     295static AtomicString classNameForShadowRootSize(const IntSize& viewContentsSize, const Node* node)
     296{
     297    DEFINE_STATIC_LOCAL(const AtomicString, plugInTinySizeClassName, ("tiny", AtomicString::ConstructFromLiteral));
     298    DEFINE_STATIC_LOCAL(const AtomicString, plugInSmallSizeClassName, ("small", AtomicString::ConstructFromLiteral));
     299    DEFINE_STATIC_LOCAL(const AtomicString, plugInMediumSizeClassName, ("medium", AtomicString::ConstructFromLiteral));
     300    DEFINE_STATIC_LOCAL(const AtomicString, plugInLargeSizeClassName, ("large", AtomicString::ConstructFromLiteral));
     301
     302    LayoutRect plugInClipRect = node->renderer()->absoluteClippedOverflowRect();
     303    LayoutRect viewContentsRect(LayoutPoint::zero(), LayoutSize(viewContentsSize));
     304    if (!viewContentsRect.contains(plugInClipRect)) {
     305        LOG(Plugins, "%p Plug-in rect: (%d %d, %d %d) not contained in document of size %d %d", node, plugInClipRect.pixelSnappedX(), plugInClipRect.pixelSnappedY(), plugInClipRect.pixelSnappedWidth(), plugInClipRect.pixelSnappedHeight(), viewContentsSize.width(), viewContentsSize.height());
     306        return nullAtom;
     307    }
     308
     309    if (plugInClipRect.pixelSnappedWidth() < sizingTinyDimensionThreshold || plugInClipRect.pixelSnappedHeight() < sizingTinyDimensionThreshold) {
     310        LOG(Plugins, "%p Tiny Size: %d %d", node, plugInClipRect.pixelSnappedWidth(), plugInClipRect.pixelSnappedHeight());
     311        return plugInTinySizeClassName;
     312    }
     313
     314    if (plugInClipRect.pixelSnappedWidth() < sizingSmallWidthThreshold) {
     315        LOG(Plugins, "%p Small Size: %d %d", node, plugInClipRect.pixelSnappedWidth(), plugInClipRect.pixelSnappedHeight());
     316        return plugInSmallSizeClassName;
     317    }
     318
     319    if (plugInClipRect.pixelSnappedWidth() < sizingMediumWidthThreshold) {
     320        LOG(Plugins, "%p Medium Size: %d %d", node, plugInClipRect.pixelSnappedWidth(), plugInClipRect.pixelSnappedHeight());
     321        return plugInMediumSizeClassName;
     322    }
     323
     324    return plugInLargeSizeClassName;
     325}
     326
     327void HTMLPlugInImageElement::updateSnapshotInfo()
     328{
     329    ShadowRoot* root = userAgentShadowRoot();
     330    if (!root)
     331        return;
     332
     333    Element* shadowContainer = static_cast<Element*>(root->firstChild());
     334    shadowContainer->setAttribute(classAttr, classNameForShadowRootSize(document()->page()->mainFrame()->view()->contentsSize(), this));   
     335}
     336
    291337void HTMLPlugInImageElement::didAddUserAgentShadowRoot(ShadowRoot* root)
    292338{
     
    379425    }
    380426
    381     if (plugInClipRect.pixelSnappedWidth() < autoShowLabelSizeThresholdWidth
    382         || plugInClipRect.pixelSnappedHeight() < autoShowLabelSizeThresholdHeight) {
     427    if (plugInClipRect.pixelSnappedWidth() < autoShowLabelSizeWidthThreshold
     428        || plugInClipRect.pixelSnappedHeight() < autoShowLabelSizeHeightThreshold) {
    383429        LOG(Plugins, "%p Size: %d %d", node, plugInClipRect.pixelSnappedWidth(), plugInClipRect.pixelSnappedHeight());
    384430        return false;
     
    408454    int width = rect.width();
    409455    int height = rect.height();
    410     if (!width || !height || (width <= autoStartPlugInSizeThresholdWidth && height <= autoStartPlugInSizeThresholdHeight)) {
     456    if (!width || !height || (width <= autoStartPlugInSizeDimensionThreshold && height <= autoStartPlugInSizeDimensionThreshold)) {
    411457        LOG(Plugins, "%p Plug-in is %dx%d, set to play", this, width, height);
    412458        return;
  • trunk/Source/WebCore/html/HTMLPlugInImageElement.h

    r142507 r142685  
    6464
    6565    void userDidClickSnapshot(PassRefPtr<MouseEvent>);
     66    void updateSnapshotInfo();
    6667
    6768    // Plug-in URL might not be the same as url() with overriding parameters.
  • trunk/Source/WebCore/page/FrameView.cpp

    r142647 r142685  
    13251325}
    13261326
    1327 void FrameView::addWidgetToUpdate(RenderEmbeddedObject* object)
     1327void FrameView::addWidgetToUpdate(RenderObject* object)
    13281328{
    13291329    if (!m_widgetUpdateSet)
    1330         m_widgetUpdateSet = adoptPtr(new RenderEmbeddedObjectSet);
     1330        m_widgetUpdateSet = adoptPtr(new RenderObjectSet);
    13311331
    13321332    // Tell the DOM element that it needs a widget update.
     
    13401340}
    13411341
    1342 void FrameView::removeWidgetToUpdate(RenderEmbeddedObject* object)
     1342void FrameView::removeWidgetToUpdate(RenderObject* object)
    13431343{
    13441344    if (!m_widgetUpdateSet)
     
    24442444}
    24452445
    2446 void FrameView::updateWidget(RenderEmbeddedObject* object)
     2446void FrameView::updateWidget(RenderObject* object)
    24472447{
    24482448    ASSERT(!object->node() || object->node()->isElementNode());
     
    24542454        return;
    24552455
    2456     // No need to update if it's already crashed or known to be missing.
    2457     if (object->showsUnavailablePluginIndicator())
    2458         return;
    2459 
    2460     // FIXME: This could turn into a real virtual dispatch if we defined
    2461     // updateWidget(PluginCreationOption) on HTMLElement.
    2462     if (ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag) || ownerElement->hasTagName(appletTag)) {
    2463         HTMLPlugInImageElement* pluginElement = static_cast<HTMLPlugInImageElement*>(ownerElement);
    2464         if (pluginElement->needsWidgetUpdate())
    2465             pluginElement->updateWidget(CreateAnyWidgetType);
    2466     }
    2467     // FIXME: It is not clear that Media elements need or want this updateWidget() call.
     2456    if (object->isEmbeddedObject()) {
     2457        RenderEmbeddedObject* embeddedObject = static_cast<RenderEmbeddedObject*>(object);
     2458        // No need to update if it's already crashed or known to be missing.
     2459        if (embeddedObject->showsUnavailablePluginIndicator())
     2460            return;
     2461
     2462        // FIXME: This could turn into a real virtual dispatch if we defined
     2463        // updateWidget(PluginCreationOption) on HTMLElement.
     2464        if (ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag) || ownerElement->hasTagName(appletTag)) {
     2465            HTMLPlugInImageElement* pluginElement = static_cast<HTMLPlugInImageElement*>(ownerElement);
     2466            if (pluginElement->needsWidgetUpdate())
     2467                pluginElement->updateWidget(CreateAnyWidgetType);
     2468        }
     2469        // FIXME: It is not clear that Media elements need or want this updateWidget() call.
    24682470#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
    2469     else if (ownerElement->isMediaElement())
    2470         static_cast<HTMLMediaElement*>(ownerElement)->updateWidget(CreateAnyWidgetType);
    2471 #endif
    2472     else
    2473         ASSERT_NOT_REACHED();
    2474 
    2475     // Caution: it's possible the object was destroyed again, since loading a
    2476     // plugin may run any arbitrary javascript.
    2477     object->updateWidgetPosition();
     2471        else if (ownerElement->isMediaElement())
     2472            static_cast<HTMLMediaElement*>(ownerElement)->updateWidget(CreateAnyWidgetType);
     2473#endif
     2474        else
     2475            ASSERT_NOT_REACHED();
     2476
     2477        // Caution: it's possible the object was destroyed again, since loading a
     2478        // plugin may run any arbitrary JavaScript.
     2479        embeddedObject->updateWidgetPosition();
     2480    } else if (object->isSnapshottedPlugIn()) {
     2481        if (ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag)) {
     2482            HTMLPlugInImageElement* pluginElement = static_cast<HTMLPlugInImageElement*>(ownerElement);
     2483            pluginElement->updateSnapshotInfo();
     2484        }
     2485    }
    24782486}
    24792487
     
    24852493    size_t size = m_widgetUpdateSet->size();
    24862494
    2487     Vector<RenderEmbeddedObject*> objects;
    2488     objects.reserveCapacity(size);
    2489 
    2490     RenderEmbeddedObjectSet::const_iterator end = m_widgetUpdateSet->end();
    2491     for (RenderEmbeddedObjectSet::const_iterator it = m_widgetUpdateSet->begin(); it != end; ++it) {
    2492         objects.uncheckedAppend(*it);
    2493         (*it)->ref();
     2495    Vector<RenderObject*> objects;
     2496    objects.reserveInitialCapacity(size);
     2497
     2498    RenderObjectSet::const_iterator end = m_widgetUpdateSet->end();
     2499    for (RenderObjectSet::const_iterator it = m_widgetUpdateSet->begin(); it != end; ++it) {
     2500        RenderObject* object = *it;
     2501        objects.uncheckedAppend(object);
     2502        if (object->isEmbeddedObject()) {
     2503            RenderEmbeddedObject* embeddedObject = static_cast<RenderEmbeddedObject*>(object);
     2504            embeddedObject->ref();
     2505        }
    24942506    }
    24952507
    24962508    for (size_t i = 0; i < size; ++i) {
    2497         RenderEmbeddedObject* object = objects[i];
     2509        RenderObject* object = objects[i];
    24982510        updateWidget(object);
    24992511        m_widgetUpdateSet->remove(object);
     
    25012513
    25022514    RenderArena* arena = m_frame->document()->renderArena();
    2503     for (size_t i = 0; i < size; ++i)
    2504         objects[i]->deref(arena);
     2515    for (size_t i = 0; i < size; ++i) {
     2516        RenderObject* object = objects[i];
     2517        if (object->isEmbeddedObject()) {
     2518            RenderEmbeddedObject* embeddedObject = static_cast<RenderEmbeddedObject*>(object);
     2519            embeddedObject->deref(arena);
     2520        }
     2521    }
    25052522   
    25062523    return m_widgetUpdateSet->isEmpty();
  • trunk/Source/WebCore/page/FrameView.h

    r142647 r142685  
    255255    void setSafeToPropagateScrollToParent(bool isSafe) { m_safeToPropagateScrollToParent = isSafe; }
    256256
    257     void addWidgetToUpdate(RenderEmbeddedObject*);
    258     void removeWidgetToUpdate(RenderEmbeddedObject*);
     257    void addWidgetToUpdate(RenderObject*);
     258    void removeWidgetToUpdate(RenderObject*);
    259259
    260260    virtual void paintContents(GraphicsContext*, const IntRect& damageRect);
     
    471471
    472472    bool updateWidgets();
    473     void updateWidget(RenderEmbeddedObject*);
     473    void updateWidget(RenderObject*);
    474474    void scrollToAnchor();
    475475    void scrollPositionChanged();
     
    494494    LayoutSize m_margins;
    495495   
    496     typedef HashSet<RenderEmbeddedObject*> RenderEmbeddedObjectSet;
    497     OwnPtr<RenderEmbeddedObjectSet> m_widgetUpdateSet;
     496    typedef HashSet<RenderObject*> RenderObjectSet;
     497    OwnPtr<RenderObjectSet> m_widgetUpdateSet;
    498498    RefPtr<Frame> m_frame;
    499499
  • trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp

    r142507 r142685  
    126126}
    127127
     128void RenderSnapshottedPlugIn::layout()
     129{
     130    StackStats::LayoutCheckPoint layoutCheckPoint;
     131    LayoutSize oldSize = contentBoxRect().size();
     132
     133    RenderBlock::layout();
     134
     135    LayoutSize newSize = contentBoxRect().size();
     136    if (newSize == oldSize)
     137        return;
     138
     139    if (document()->view())
     140        document()->view()->addWidgetToUpdate(this);
     141}
     142
    128143void RenderSnapshottedPlugIn::updateSnapshot(PassRefPtr<Image> image)
    129144{
  • trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.h

    r142507 r142685  
    6060    void repaintLabel();
    6161
     62    virtual void layout() OVERRIDE;
     63
    6264    enum ShowReason {
    6365        UserMousedOver,
Note: See TracChangeset for help on using the changeset viewer.