WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
Bug 131553
Snapshotted plugins may need to be restarted if style properties are changed after initial load of plugin.
https://bugs.webkit.org/show_bug.cgi?id=131553
Summary
Snapshotted plugins may need to be restarted if style properties are changed ...
Roger Fong
Reported
2014-04-11 11:55:49 PDT
When looking at the method subframeLoaderWillCreatePlugin you'll notice that the state of the plugin sometimes can depend on the style. The style can change at any point. It can also be resolved after the initial load of the plugin, which could cause a plugin to be snapshotted when it shouldn't be. For example, consider a plugin that is styled to be 1x1. The 1x1 plugin should never be snapshotted but if the style isn't resolved before the initial load of the plugin we assume the default RenderReplaced size for the plugin (300 x 150). A plugin at this size will indeed get snapshotted. Thus we end up with a 1x1 plugin that is snapshotted. When performing postLayoutTasks we checkSnapshotStatus. I think this would be a good place to also check to see if the style conditions are met. If they are and the plugin is currently snapshotted then we should restart the plugin so that it actually runs.
Attachments
patch
(4.02 KB, patch)
2014-04-11 12:15 PDT
,
Roger Fong
no flags
Details
Formatted Diff
Diff
patch
(6.99 KB, patch)
2014-04-11 16:03 PDT
,
Roger Fong
simon.fraser
: review-
Details
Formatted Diff
Diff
patch
(7.02 KB, patch)
2014-04-11 16:38 PDT
,
Roger Fong
darin
: review+
Details
Formatted Diff
Diff
patch
(12.08 KB, patch)
2014-04-14 17:20 PDT
,
Roger Fong
thorton
: review+
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Roger Fong
Comment 1
2014-04-11 12:09:26 PDT
<
rdar://problem/15443375
>
Roger Fong
Comment 2
2014-04-11 12:15:51 PDT
Created
attachment 229149
[details]
patch
Simon Fraser (smfr)
Comment 3
2014-04-11 13:17:41 PDT
Comment on
attachment 229149
[details]
patch View in context:
https://bugs.webkit.org/attachment.cgi?id=229149&action=review
> Source/WebCore/html/HTMLPlugInImageElement.cpp:620 > + auto& style = renderEmbedded.style(); > + bool isFullPage = is100Percent(style.width()) && is100Percent(style.height()); > + IntSize visibleViewSize = document().frame()->view()->visibleSize(); > + float contentArea = contentWidth * contentHeight; > + float visibleArea = visibleViewSize.width() * visibleViewSize.height(); > + if (isFullPage && contentArea > visibleArea * sizingFullPageAreaRatioThreshold) {
You should share this code with HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn().
Brent Fulgham
Comment 4
2014-04-11 15:23:24 PDT
Comment on
attachment 229149
[details]
patch View in context:
https://bugs.webkit.org/attachment.cgi?id=229149&action=review
> Source/WebCore/html/HTMLPlugInImageElement.cpp:634 > + checkSizeChangeForSnapshotting();
This has weird indention. Is this the only thing that the 'if' statement is meant to control? Or do you need brackets so the return is part of this test, too?
> Source/WebCore/html/HTMLPlugInImageElement.cpp:640 > + }
Bad whitespace.
Roger Fong
Comment 5
2014-04-11 16:03:52 PDT
Created
attachment 229173
[details]
patch
Simon Fraser (smfr)
Comment 6
2014-04-11 16:09:59 PDT
Comment on
attachment 229173
[details]
patch View in context:
https://bugs.webkit.org/attachment.cgi?id=229173&action=review
> Source/WebCore/html/HTMLPlugInImageElement.cpp:604 > +bool HTMLPlugInImageElement::isTopLevelFullPage(const RenderEmbeddedObject& renderEmbedded, int contentWidth, int contentHeight)
Fewer weird abbreviations please! isTopLevelFullPagePlugin(const RenderEmbeddedObject& embeddedObject, ...
> Source/WebCore/html/HTMLPlugInImageElement.cpp:606 > + if (document().frame()->isMainFrame()) {
if (!document().frame()->isMainFrame()) return false
> Source/WebCore/html/HTMLPlugInImageElement.cpp:613 > + if (isFullPage && contentArea > visibleArea * sizingFullPageAreaRatioThreshold) > + return true;
return isFullPage && (contentArea > visibleArea * sizingFullPageAreaRatioThreshold);
> Source/WebCore/html/HTMLPlugInImageElement.cpp:622 > + if (contentWidth <= sizingTinyDimensionThreshold || contentHeight <= sizingTinyDimensionThreshold) > + return true; > + return false;
return (contentWidth <= sizingTinyDimensionThreshold || contentHeight <= sizingTinyDimensionThreshold) This could be a local static function.
> Source/WebCore/html/HTMLPlugInImageElement.cpp:630 > + auto& renderEmbedded = toRenderEmbeddedObject(*this->renderer());
Why not use the renderEmbeddedObject() function (and check its return value)?
> Source/WebCore/html/HTMLPlugInImageElement.cpp:642 > + if (displayState() == Playing) > + checkSizeChangeForSnapshotting();
Wrong indentation.
> Source/WebCore/html/HTMLPlugInImageElement.h:144 > + bool isTopLevelFullPage(const RenderEmbeddedObject&, int contentWidth, int contentHeight);
Should be a const function.
Roger Fong
Comment 7
2014-04-11 16:28:42 PDT
(In reply to
comment #6
)
> (From update of
attachment 229173
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=229173&action=review
> > > Source/WebCore/html/HTMLPlugInImageElement.cpp:604 > > +bool HTMLPlugInImageElement::isTopLevelFullPage(const RenderEmbeddedObject& renderEmbedded, int contentWidth, int contentHeight) > > Fewer weird abbreviations please! > isTopLevelFullPagePlugin(const RenderEmbeddedObject& embeddedObject, ... > > > Source/WebCore/html/HTMLPlugInImageElement.cpp:606 > > + if (document().frame()->isMainFrame()) { > > if (!document().frame()->isMainFrame()) > return false > > > Source/WebCore/html/HTMLPlugInImageElement.cpp:613 > > + if (isFullPage && contentArea > visibleArea * sizingFullPageAreaRatioThreshold) > > + return true; > > return isFullPage && (contentArea > visibleArea * sizingFullPageAreaRatioThreshold); > > > Source/WebCore/html/HTMLPlugInImageElement.cpp:622 > > + if (contentWidth <= sizingTinyDimensionThreshold || contentHeight <= sizingTinyDimensionThreshold) > > + return true; > > + return false; > > return (contentWidth <= sizingTinyDimensionThreshold || contentHeight <= sizingTinyDimensionThreshold) > > This could be a local static function. > > > Source/WebCore/html/HTMLPlugInImageElement.cpp:630 > > + auto& renderEmbedded = toRenderEmbeddedObject(*this->renderer()); > > Why not use the renderEmbeddedObject() function (and check its return value)?
Should I assert that it's not null? When would it not exist?
> > > Source/WebCore/html/HTMLPlugInImageElement.cpp:642 > > + if (displayState() == Playing) > > + checkSizeChangeForSnapshotting(); > > Wrong indentation. > > > Source/WebCore/html/HTMLPlugInImageElement.h:144 > > + bool isTopLevelFullPage(const RenderEmbeddedObject&, int contentWidth, int contentHeight); > > Should be a const function.
Roger Fong
Comment 8
2014-04-11 16:38:08 PDT
Created
attachment 229179
[details]
patch
Darin Adler
Comment 9
2014-04-12 13:04:07 PDT
Comment on
attachment 229179
[details]
patch View in context:
https://bugs.webkit.org/attachment.cgi?id=229179&action=review
> Source/WebCore/html/HTMLPlugInImageElement.cpp:604 > +static inline bool isSmallerThanTinySizingThreshold(int contentWidth, int contentHeight)
This should take a LayoutSize instead of two ints for the height and width. I would suggest just calling it size. I’m not sure that “content size” says anything more than “size” does. What other size would it be? Maybe a const LayoutSize& or maybe just LayoutSize would be better. Or maybe we should just have this function take a RenderEmbeddedObject& instead. That would be more convenient in both call sites.
> Source/WebCore/html/HTMLPlugInImageElement.cpp:606 > + return (contentWidth <= sizingTinyDimensionThreshold || contentHeight <= sizingTinyDimensionThreshold);
No need for the parentheses here.
> Source/WebCore/html/HTMLPlugInImageElement.cpp:609 > +bool HTMLPlugInImageElement::isTopLevelFullPagePlugin(const RenderEmbeddedObject* renderEmbedded, int contentWidth, int contentHeight) const
This should take a RenderEmbeddedObject&, not a const RenderEmbeddedObject*. Or const if you insist, but it should not be a pointer since it can never be null. Also, I suggest naming this just “renderer”. There’s no need to encode the type in the name. This function should get the contentBoxRect from the renderer. It’s not really valuable to pass it in, since both callers compute it the same way.
> Source/WebCore/html/HTMLPlugInImageElement.cpp:612 > + if (!document().frame()->isMainFrame()) > + return false;
Since we use Frame more than once in this function I suggest putting it in a reference: Frame& frame = *document().frame();
> Source/WebCore/html/HTMLPlugInImageElement.cpp:615 > + bool isFullPage = is100Percent(style.width()) && is100Percent(style.height());
Instead of a boolean, we should have an early return here. That’s one of the advantages of moving this to a separate function. No need to compute the areas below if the styles aren’t 100%.
> Source/WebCore/html/HTMLPlugInImageElement.cpp:619 > + IntSize visibleViewSize = document().frame()->view()->visibleSize(); > + float contentArea = contentWidth * contentHeight; > + float visibleArea = visibleViewSize.width() * visibleViewSize.height(); > + return isFullPage && (contentArea > visibleArea * sizingFullPageAreaRatioThreshold);
If we made an area helper function (overloaded for IntSize and LayoutSize) then these four lines could be written in one line like this: return area(renderer.contentBoxRect()) > area(frame.view()->visibleSize()) * sizingFullPageAreaRatioThreshold; I think that’s better.
> Source/WebCore/html/HTMLPlugInImageElement.cpp:627 > + RenderEmbeddedObject* renderEmbedded = renderEmbeddedObject();
This should be a reference. The code above will already crash if the renderer is null so there is no point in using a pointer. The type of this should be RenderSnapshottedPlugIn, not RenderEmbeddedObject. We always want to use the most-specific type we can, based on the type check we did. And here, the type check is isSnapshottedPlugIn, not isEmbeddedObject.
> Source/WebCore/html/HTMLPlugInImageElement.cpp:628 > + ASSERT(renderer);
Looks like this won’t compile, because the code above uses the name renderEmbedded.
> Source/WebCore/html/HTMLPlugInImageElement.cpp:732 > + RenderEmbeddedObject* renderer = renderEmbeddedObject();
This local variable should remain a reference, not a pointer. The patch changes it to a pointer for no good reason.
Dean Jackson
Comment 10
2014-04-13 23:22:09 PDT
(In reply to
comment #9
)
> > Source/WebCore/html/HTMLPlugInImageElement.cpp:619 > > + IntSize visibleViewSize = document().frame()->view()->visibleSize(); > > + float contentArea = contentWidth * contentHeight; > > + float visibleArea = visibleViewSize.width() * visibleViewSize.height(); > > + return isFullPage && (contentArea > visibleArea * sizingFullPageAreaRatioThreshold); > > If we made an area helper function (overloaded for IntSize and LayoutSize) then these four lines could be written in one line like this: > > return area(renderer.contentBoxRect()) > area(frame.view()->visibleSize()) * sizingFullPageAreaRatioThreshold; >
There already is an area() member function on IntSize. We don't have one on LayoutSize. I like the idea of a helper function so here is a patch:
http://webkit.org/b/131606
Jon Lee
Comment 11
2014-04-14 10:18:27 PDT
I have some concerns here that it’s possible for a plugin to resize thrice to get to a non snapshotted state with this patch. - Plugin starts off small, decision = MaySnapshotWhenResized - Plugin gets resized larger, decision = Snapshotted - Plugin gets resized small again; we restart the plugin but decision remains Snapshotted - Plugin gets resized large again; the plugin does not get snapshotted I think we need to make sure that the restart path we’re allowing here is specifically the case where the plugin starts off at the default plugin size (300x150) and then gets resized later to a small size.
Jon Lee
Comment 12
2014-04-14 10:22:29 PDT
Also, can we write a test for this?
Roger Fong
Comment 13
2014-04-14 10:52:43 PDT
(In reply to
comment #11
)
> I have some concerns here that it’s possible for a plugin to resize thrice to get to a non snapshotted state with this patch. > > - Plugin starts off small, decision = MaySnapshotWhenResized > > - Plugin gets resized larger, decision = Snapshotted > > - Plugin gets resized small again; we restart the plugin but decision remains Snapshotted > > - Plugin gets resized large again; the plugin does not get snapshotted
Shouldn't we just change the decision everytime the plugin gets resized?
> > I think we need to make sure that the restart path we’re allowing here is specifically the case where the plugin starts off at the default plugin size (300x150) and then gets resized later to a small size.
Roger Fong
Comment 14
2014-04-14 10:55:32 PDT
(In reply to
comment #12
)
> Also, can we write a test for this?
Hmm...I guess we could do something have a timer to apply CSS and then check to see if the plugin has shadow dom content (the snapshot), I'm assuming this is doable via layout tests somehow.
Roger Fong
Comment 15
2014-04-14 10:57:23 PDT
(In reply to
comment #13
)
> (In reply to
comment #11
) > > I have some concerns here that it’s possible for a plugin to resize thrice to get to a non snapshotted state with this patch. > > > > - Plugin starts off small, decision = MaySnapshotWhenResized > > > > - Plugin gets resized larger, decision = Snapshotted > > > > - Plugin gets resized small again; we restart the plugin but decision remains Snapshotted
Wouldn't setting decision = MaySnapshotWhenResized here (which is the change I made comes into play), do the trick?
> > > > - Plugin gets resized large again; the plugin does not get snapshotted > > Shouldn't we just change the decision everytime the plugin gets resized? > > > > > I think we need to make sure that the restart path we’re allowing here is specifically the case where the plugin starts off at the default plugin size (300x150) and then gets resized later to a small size.
Roger Fong
Comment 16
2014-04-14 17:20:59 PDT
Created
attachment 229326
[details]
patch In this version of the patch we only restart the plugin if the dimensions are changed to being too small if the existing dimensions were not specified yet (using default intrinsic size). If the dimensions were already specified then we want to stick with whatever snapshotting decision was made with those initial dimensions.
Roger Fong
Comment 17
2014-04-15 16:18:13 PDT
ping
Tim Horton
Comment 18
2014-04-15 16:27:00 PDT
Comment on
attachment 229326
[details]
patch View in context:
https://bugs.webkit.org/attachment.cgi?id=229326&action=review
This is fine with me as long as the behavior is fine with Jon/Dean, but please confirm.
> Source/WebCore/html/HTMLPlugInImageElement.cpp:609 > + int contentWidth = contentRect.width(); > + int contentHeight = contentRect.height();
why the temporaries? they're only used once below.
> Source/WebCore/html/HTMLPlugInImageElement.cpp:646 > + if (!renderer()->isSnapshottedPlugIn()) {
if you move this above the previous block, you can get rid of that check in its condition
> LayoutTests/plugins/snapshotting/set-plugin-size-to-tiny.html:15 > + testRunner.notifyDone()
semicolon
Roger Fong
Comment 19
2014-04-15 17:27:32 PDT
Committed
http://trac.webkit.org/changeset/167339
w/ Tim's comments. Behavior was discussed with Jon earlier. thx!
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug