HTMLMediaElement: set `muted_` when cloning element with muted attribute.

This CL works around the fact that cloning does not call the parser
callbacks and the HTML specifications require the attribute to only
have an effect when the element was created. There is unfortunately
no notification that the element creation from `cloneNode()` happens
so we instead rely on a callback meant for something slightly different.

Bug: 811743
Change-Id: Ib7ac55088b9eaad23f9bce0cfc8366fec6fc5b0d
Reviewed-on: https://chromium-review.googlesource.com/937504
Commit-Queue: Mounir Lamouri <mlamouri@chromium.org>
Reviewed-by: Philip J├Ągenstedt <foolip@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#539207}(cherry picked from commit 0d23cbfab31479d700140aa5d26d70d857f7be48)
Reviewed-on: https://chromium-review.googlesource.com/939561
Reviewed-by: Mounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/branch-heads/3325@{#605}
Cr-Branched-From: bc084a8b5afa3744a74927344e304c02ae54189f-refs/heads/master@{#530369}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/user-interface/muted.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/user-interface/muted.html
index 906350d..eb6d2ac6 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/user-interface/muted.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/user-interface/muted.html
@@ -148,5 +148,22 @@
     assert_true(m.hasAttribute('muted'));
     assert_true(m.muted);
   }, 'getting ' + tagName + '.muted with muted="" (document.write-created)');
+
+  test(function() {
+    var m = document.createElement(tagName);
+    m.setAttribute('muted', '');
+
+    var c = m.cloneNode(true);
+    assert_true(c.muted);
+  }, 'cloning ' + tagName + ' propagates muted (script-created)');
+
+  test(function() {
+    var div = document.createElement('div');
+    div.innerHTML = '<' + tagName + ' muted>';
+    m = div.firstChild;
+
+    var c = m.cloneNode(true);
+    assert_true(c.muted);
+  }, 'cloning ' + tagName + ' propagates muted (innerHTML-created)');
 });
 </script>
diff --git a/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp
index dfea559..8cdff94 100644
--- a/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp
@@ -657,6 +657,18 @@
     muted_ = true;
 }
 
+// This method is being used as a way to know that cloneNode finished cloning
+// attribute as there is no callback notifying about the end of a cloning
+// operation. Indeed, it is required per spec to set the muted state based on
+// the content attribute when the object is created.
+void HTMLMediaElement::CloneNonAttributePropertiesFrom(const Element& other,
+                                                       CloneChildrenFlag flag) {
+  HTMLElement::CloneNonAttributePropertiesFrom(other, flag);
+
+  if (FastHasAttribute(mutedAttr))
+    muted_ = true;
+}
+
 void HTMLMediaElement::FinishParsingChildren() {
   HTMLElement::FinishParsingChildren();
 
diff --git a/third_party/WebKit/Source/core/html/media/HTMLMediaElement.h b/third_party/WebKit/Source/core/html/media/HTMLMediaElement.h
index 02826f0..3ecd13e 100644
--- a/third_party/WebKit/Source/core/html/media/HTMLMediaElement.h
+++ b/third_party/WebKit/Source/core/html/media/HTMLMediaElement.h
@@ -337,6 +337,8 @@
   bool IsURLAttribute(const Attribute&) const override;
   void AttachLayoutTree(AttachContext&) override;
   void ParserDidSetAttributes() override;
+  void CloneNonAttributePropertiesFrom(const Element&,
+                                       CloneChildrenFlag) override;
 
   InsertionNotificationRequest InsertedInto(ContainerNode*) override;
   void RemovedFrom(ContainerNode*) override;