REGRESSION: Plugin replaced YouTube Flash videos always have the same width
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jul 2016 21:06:51 +0000 (21:06 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jul 2016 21:06:51 +0000 (21:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=159998
<rdar://problem/27462285>

Reviewed by Simon Fraser.

Source/WebCore:

Fixes an issue where the width of a plugin replaced YouTube video loaded via an HTML embed
element would always have the same width regardless of value of the width attribute.

For YouTube Flash videos the YouTube plugin replacement substitutes a shadow DOM subtree
for the default renderer of an HTML embed element. The root of this shadow DOM subtree
is an HTML div element. Currently we set inline styles on this <div> when it is instantiated.
In particular, we set inline display and position to "inline-block" and "relative", respectively,
and set an invalid height and width (we specify a font weight value instead of a CSS length value
- this causes an ASSERT_NOT_REACHED() assertion failure in StyleBuilderConverter::convertLengthSizing()
in a debug build). These styles never worked as intended and we ultimately created an inline
renderer (ignoring display "inline-block") that had auto width and height. Instead it is sufficient
to remove all these inline styles and create a RenderBlockFlow renderer for this <div> so that it
renders as a block, non-replaced element to achieve the intended illusion that the <embed> is a
single element.

* html/shadow/YouTubeEmbedShadowElement.cpp: Remove unused header HTMLEmbedElement.h and include
header RenderBlockFlow.h. Also update copyright in license block.
(WebCore::YouTubeEmbedShadowElement::YouTubeEmbedShadowElement): Remove inline styles as these
never worked as intended.
(WebCore::YouTubeEmbedShadowElement::createElementRenderer): Override; create a block-flow
renderer for us so that we layout as a block, non-replaced element.
* html/shadow/YouTubeEmbedShadowElement.h:

LayoutTests:

Unskip existing iOS layout tests, update tests and expected results.

* platform/ios-simulator/TestExpectations:
* platform/ios-simulator/ios/plugin/youtube-flash-plugin-iframe-expected.txt: Updated expected result based on the
changes to test youtube-flash-plugin-iframe.html.
* platform/ios-simulator/ios/plugin/youtube-flash-plugin-iframe-no-height-or-width-expected.txt: Updated expected result
based on the changes to test youtube-flash-plugin-iframe-no-height-or-width.html.
* platform/ios-simulator/ios/plugin/youtube-flash-plugin-iframe-no-height-or-width.html: Modified to check the
width of each embedded YouTube video to ensure that we respect it (if specified).
* platform/ios-simulator/ios/plugin/youtube-flash-plugin-iframe.html: Substitute pseudo id -webkit-plugin-replacement
for -apple-youtube-shadow-iframe as the later was renamed to the former in <https://trac.webkit.org/changeset/168442>.
Fix misspelling of the word "embed" in a comment.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@203522 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/platform/ios-simulator/TestExpectations
LayoutTests/platform/ios-simulator/ios/plugin/youtube-flash-plugin-iframe-expected.txt
LayoutTests/platform/ios-simulator/ios/plugin/youtube-flash-plugin-iframe-no-height-or-width-expected.txt
LayoutTests/platform/ios-simulator/ios/plugin/youtube-flash-plugin-iframe-no-height-or-width.html
LayoutTests/platform/ios-simulator/ios/plugin/youtube-flash-plugin-iframe.html
Source/WebCore/ChangeLog
Source/WebCore/html/shadow/YouTubeEmbedShadowElement.cpp
Source/WebCore/html/shadow/YouTubeEmbedShadowElement.h

index dc1020f..63f4f23 100644 (file)
@@ -1,3 +1,24 @@
+2016-07-21  Daniel Bates  <dabates@apple.com>
+
+        REGRESSION: Plugin replaced YouTube Flash videos always have the same width
+        https://bugs.webkit.org/show_bug.cgi?id=159998
+        <rdar://problem/27462285>
+
+        Reviewed by Simon Fraser.
+
+        Unskip existing iOS layout tests, update tests and expected results.
+
+        * platform/ios-simulator/TestExpectations:
+        * platform/ios-simulator/ios/plugin/youtube-flash-plugin-iframe-expected.txt: Updated expected result based on the
+        changes to test youtube-flash-plugin-iframe.html.
+        * platform/ios-simulator/ios/plugin/youtube-flash-plugin-iframe-no-height-or-width-expected.txt: Updated expected result
+        based on the changes to test youtube-flash-plugin-iframe-no-height-or-width.html.
+        * platform/ios-simulator/ios/plugin/youtube-flash-plugin-iframe-no-height-or-width.html: Modified to check the
+        width of each embedded YouTube video to ensure that we respect it (if specified).
+        * platform/ios-simulator/ios/plugin/youtube-flash-plugin-iframe.html: Substitute pseudo id -webkit-plugin-replacement
+        for -apple-youtube-shadow-iframe as the later was renamed to the former in <https://trac.webkit.org/changeset/168442>.
+        Fix misspelling of the word "embed" in a comment.
+
 2016-07-21  Ryan Haddad  <ryanhaddad@apple.com>
 
         Marking inspector/codemirror/prettyprinting-javascript.html as a flaky timeout on mac debug.
index d551769..1db8c64 100644 (file)
@@ -2556,8 +2556,6 @@ webkit.org/b/145432 media/video-transformed-by-javascript.html [ Failure ]
 
 # iOS tests that assert:
 platform/ios-simulator/ios/fast/text/combining-enclosing-keycap.html
-platform/ios-simulator/ios/plugin/youtube-flash-plugin-iframe-no-height-or-width.html
-platform/ios-simulator/ios/plugin/youtube-flash-plugin-iframe.html
 
 # Kerning, Ligatures, and Printer Fonts caused these tests to fail.
 # The following tests are reftests (and also fail on Mac):
index 1dadfc4..02d6e65 100644 (file)
@@ -16,11 +16,11 @@ PASS elinkEmbed.tagName is "EMBED"
 PASS objectEmbed.tagName is "EMBED"
 PASS objectNoEmbed.tagName is "OBJECT"
 PASS document.querySelectorAll("iframe").length is 1
-PASS internals.shadowPseudoId(normalEmbedShadowRoot.firstChild) is "-apple-youtube-shadow-iframe"
+PASS internals.shadowPseudoId(normalEmbedShadowRoot.firstChild) is "-webkit-plugin-replacement"
 PASS normalEmbedShadowRoot.firstChild.firstChild.tagName is "IFRAME"
-PASS internals.shadowPseudoId(objectEmbedShadowRoot.firstChild) is "-apple-youtube-shadow-iframe"
+PASS internals.shadowPseudoId(objectEmbedShadowRoot.firstChild) is "-webkit-plugin-replacement"
 PASS objectEmbedShadowRoot.firstChild.firstChild.tagName is "IFRAME"
-PASS internals.shadowPseudoId(objectNoEmbedShadowRoot.firstChild) is "-apple-youtube-shadow-iframe"
+PASS internals.shadowPseudoId(objectNoEmbedShadowRoot.firstChild) is "-webkit-plugin-replacement"
 PASS objectNoEmbedShadowRoot.firstChild.firstChild.tagName is "IFRAME"
 Normal Embed:
 
index 874390a..c6b37f0 100644 (file)
@@ -12,12 +12,16 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 PASS successfullyParsed is true
 
 TEST COMPLETE
+PASS getComputedStyle(embedNoHeight).width is "425px"
 PASS getComputedStyle(embedNoHeight).height is "150px"
 PASS getComputedStyle(embedNoWidth).width is "300px"
+PASS getComputedStyle(embedNoWidth).height is "350px"
 PASS getComputedStyle(embedNoWidthHeight).width is "300px"
 PASS getComputedStyle(embedNoWidthHeight).height is "150px"
+PASS getComputedStyle(objectNoHeight).width is "425px"
 PASS getComputedStyle(objectNoHeight).height is "150px"
 PASS getComputedStyle(objectNoWidth).width is "300px"
+PASS getComputedStyle(objectNoWidth).height is "350px"
 PASS getComputedStyle(objectNoWidthHeight).width is "300px"
 PASS getComputedStyle(objectNoWidthHeight).height is "150px"
 Embed without height:
index af5fdf2..9075a6d 100644 (file)
@@ -16,20 +16,24 @@ function Test()
 {
     setTimeout(function() {
         embedNoHeight = document.getElementById('embed-no-height');
-        shouldBe('getComputedStyle(embedNoHeight).height', '"150px"')
+        shouldBe('getComputedStyle(embedNoHeight).width', '"425px"');
+        shouldBe('getComputedStyle(embedNoHeight).height', '"150px"');
 
         embedNoWidth = document.getElementById('embed-no-width');
-        shouldBe('getComputedStyle(embedNoWidth).width', '"300px"')
+        shouldBe('getComputedStyle(embedNoWidth).width', '"300px"');
+        shouldBe('getComputedStyle(embedNoWidth).height', '"350px"');
 
         embedNoWidthHeight = document.getElementById('embed-no-width-or-height');
         shouldBe('getComputedStyle(embedNoWidthHeight).width', '"300px"');
         shouldBe('getComputedStyle(embedNoWidthHeight).height', '"150px"');
 
         objectNoHeight = document.getElementById('object-no-height');
-        shouldBe('getComputedStyle(objectNoHeight).height', '"150px"')
+        shouldBe('getComputedStyle(objectNoHeight).width', '"425px"');
+        shouldBe('getComputedStyle(objectNoHeight).height', '"150px"');
 
         objectNoWidth = document.getElementById('object-no-width');
-        shouldBe('getComputedStyle(objectNoWidth).width', '"300px"')
+        shouldBe('getComputedStyle(objectNoWidth).width', '"300px"');
+        shouldBe('getComputedStyle(objectNoWidth).height', '"350px"');
 
         objectNoWidthHeight = document.getElementById('object-no-width-or-height');
         shouldBe('getComputedStyle(objectNoWidthHeight).width', '"300px"');
index 3bed956..bc9eebe 100644 (file)
@@ -20,7 +20,7 @@ function Test()
         objectEmbed = document.getElementById('object-embed');
         objectNoEmbed = document.getElementById('object-no-embed');
 
-        // Test we don't change any embe/object tag to iframe.
+        // Test we don't change any embed/object tag to iframe.
         shouldBe('normalEmbed.tagName', '"EMBED"');
         shouldBe('elinkEmbed.tagName', '"EMBED"');
         shouldBe('objectEmbed.tagName', '"EMBED"');
@@ -31,15 +31,15 @@ function Test()
 
         // Test we have the shadow root and the iframe player.
         normalEmbedShadowRoot = internals.shadowRoot(normalEmbed);
-        shouldBe('internals.shadowPseudoId(normalEmbedShadowRoot.firstChild)', '"-apple-youtube-shadow-iframe"');
+        shouldBe('internals.shadowPseudoId(normalEmbedShadowRoot.firstChild)', '"-webkit-plugin-replacement"');
         shouldBe('normalEmbedShadowRoot.firstChild.firstChild.tagName', '"IFRAME"');
 
         objectEmbedShadowRoot = internals.shadowRoot(objectEmbed);
-        shouldBe('internals.shadowPseudoId(objectEmbedShadowRoot.firstChild)', '"-apple-youtube-shadow-iframe"');
+        shouldBe('internals.shadowPseudoId(objectEmbedShadowRoot.firstChild)', '"-webkit-plugin-replacement"');
         shouldBe('objectEmbedShadowRoot.firstChild.firstChild.tagName', '"IFRAME"');
 
         objectNoEmbedShadowRoot = internals.shadowRoot(objectNoEmbed);
-        shouldBe('internals.shadowPseudoId(objectNoEmbedShadowRoot.firstChild)', '"-apple-youtube-shadow-iframe"');
+        shouldBe('internals.shadowPseudoId(objectNoEmbedShadowRoot.firstChild)', '"-webkit-plugin-replacement"');
         shouldBe('objectNoEmbedShadowRoot.firstChild.firstChild.tagName', '"IFRAME"');
 
         var successfullyParsed = true;
index 9be8e18..f426183 100644 (file)
@@ -1,3 +1,34 @@
+2016-07-21  Daniel Bates  <dabates@apple.com>
+
+        REGRESSION: Plugin replaced YouTube Flash videos always have the same width
+        https://bugs.webkit.org/show_bug.cgi?id=159998
+        <rdar://problem/27462285>
+
+        Reviewed by Simon Fraser.
+
+        Fixes an issue where the width of a plugin replaced YouTube video loaded via an HTML embed
+        element would always have the same width regardless of value of the width attribute.
+
+        For YouTube Flash videos the YouTube plugin replacement substitutes a shadow DOM subtree
+        for the default renderer of an HTML embed element. The root of this shadow DOM subtree
+        is an HTML div element. Currently we set inline styles on this <div> when it is instantiated.
+        In particular, we set inline display and position to "inline-block" and "relative", respectively,
+        and set an invalid height and width (we specify a font weight value instead of a CSS length value
+        - this causes an ASSERT_NOT_REACHED() assertion failure in StyleBuilderConverter::convertLengthSizing()
+        in a debug build). These styles never worked as intended and we ultimately created an inline
+        renderer (ignoring display "inline-block") that had auto width and height. Instead it is sufficient
+        to remove all these inline styles and create a RenderBlockFlow renderer for this <div> so that it
+        renders as a block, non-replaced element to achieve the intended illusion that the <embed> is a
+        single element.
+
+        * html/shadow/YouTubeEmbedShadowElement.cpp: Remove unused header HTMLEmbedElement.h and include
+        header RenderBlockFlow.h. Also update copyright in license block.
+        (WebCore::YouTubeEmbedShadowElement::YouTubeEmbedShadowElement): Remove inline styles as these
+        never worked as intended.
+        (WebCore::YouTubeEmbedShadowElement::createElementRenderer): Override; create a block-flow
+        renderer for us so that we layout as a block, non-replaced element.
+        * html/shadow/YouTubeEmbedShadowElement.h:
+
 2016-07-21  Myles C. Maxfield  <mmaxfield@apple.com>
 
         [iPhone] Playing a video on tudou.com plays only sound, no video
index 695fafd..6710006 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,7 +26,7 @@
 #include "config.h"
 #include "YouTubeEmbedShadowElement.h"
 
-#include "HTMLEmbedElement.h"
+#include "RenderBlockFlow.h"
 
 namespace WebCore {
 
@@ -39,11 +39,11 @@ YouTubeEmbedShadowElement::YouTubeEmbedShadowElement(Document& document)
     : HTMLDivElement(HTMLNames::divTag, document)
 {
     setPseudo(AtomicString("-webkit-plugin-replacement", AtomicString::ConstructFromLiteral));
+}
 
-    setInlineStyleProperty(CSSPropertyDisplay, CSSValueInlineBlock);
-    setInlineStyleProperty(CSSPropertyPosition, CSSValueRelative);
-    setInlineStyleProperty(CSSPropertyWidth, CSSValue100);
-    setInlineStyleProperty(CSSPropertyHeight, CSSValue100);
+RenderPtr<RenderElement> YouTubeEmbedShadowElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
+{
+    return createRenderer<RenderBlockFlow>(*this, WTFMove(style));
 }
 
 }
index 54158bc..46a3ae7 100644 (file)
@@ -35,6 +35,8 @@ class YouTubeEmbedShadowElement final : public HTMLDivElement {
 public:
     static Ref<YouTubeEmbedShadowElement> create(Document&);
 
+    RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final;
+
 private:
     YouTubeEmbedShadowElement(Document&);
 };