Fix EditingStyle::mergeStyle()'s handling of custom properties

This patch fixes the logic of EditingStyle::mergeStyle() to correctly
handle custom properties. Currently it serializes the CSSValue and then
reparses it, which, aside from being inefficient, doesn't work for
custom properties as the custom property name is lost (since we only
have the enum value CSSPropertyVariable).

BUG=622420

Review-Url: https://codereview.chromium.org/2103043004
Cr-Commit-Position: refs/heads/master@{#410614}
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi
index bea58beb..ea144c1 100644
--- a/third_party/WebKit/Source/core/core.gypi
+++ b/third_party/WebKit/Source/core/core.gypi
@@ -4080,6 +4080,7 @@
             'dom/shadow/FlatTreeTraversalTest.cpp',
             'editing/EditingCommandTest.cpp',
             'editing/EditingStrategyTest.cpp',
+            'editing/EditingStyleTest.cpp',
             'editing/EditingTestBase.cpp',
             'editing/EditingTestBase.h',
             'editing/EditingUtilitiesTest.cpp',
diff --git a/third_party/WebKit/Source/core/css/StylePropertySet.cpp b/third_party/WebKit/Source/core/css/StylePropertySet.cpp
index 1671630..a3bcaea4 100644
--- a/third_party/WebKit/Source/core/css/StylePropertySet.cpp
+++ b/third_party/WebKit/Source/core/css/StylePropertySet.cpp
@@ -290,6 +290,8 @@
 
 bool MutableStylePropertySet::setProperty(CSSPropertyID unresolvedProperty, const String& value, bool important, StyleSheetContents* contextStyleSheet)
 {
+    DCHECK_GE(unresolvedProperty, firstCSSProperty);
+
     // Setting the value to an empty string just removes the property in both IE and Gecko.
     // Setting it to null seems to produce less consistent results, but we treat it just the same.
     if (value.isEmpty())
diff --git a/third_party/WebKit/Source/core/editing/EditingStyle.cpp b/third_party/WebKit/Source/core/editing/EditingStyle.cpp
index 163cbfb..edca536 100644
--- a/third_party/WebKit/Source/core/editing/EditingStyle.cpp
+++ b/third_party/WebKit/Source/core/editing/EditingStyle.cpp
@@ -1180,7 +1180,7 @@
         }
 
         if (mode == OverrideValues || (mode == DoNotOverrideValues && !value))
-            m_mutableStyle->setProperty(property.id(), property.value().cssText(), property.isImportant());
+            m_mutableStyle->setProperty(property.toCSSProperty());
     }
 }
 
diff --git a/third_party/WebKit/Source/core/editing/EditingStyle.h b/third_party/WebKit/Source/core/editing/EditingStyle.h
index c5215dc..0c397e9 100644
--- a/third_party/WebKit/Source/core/editing/EditingStyle.h
+++ b/third_party/WebKit/Source/core/editing/EditingStyle.h
@@ -34,6 +34,7 @@
 
 #include "core/CSSPropertyNames.h"
 #include "core/CSSValueKeywords.h"
+#include "core/CoreExport.h"
 #include "core/editing/Position.h"
 #include "core/editing/VisibleSelection.h"
 #include "core/editing/WritingDirection.h"
@@ -57,7 +58,7 @@
 class ComputedStyle;
 class StylePropertySet;
 
-class EditingStyle final : public GarbageCollected<EditingStyle> {
+class CORE_EXPORT EditingStyle final : public GarbageCollected<EditingStyle> {
 public:
 
     enum PropertiesToInclude { AllProperties, OnlyEditingInheritableProperties, EditingPropertiesInEffect };
diff --git a/third_party/WebKit/Source/core/editing/EditingStyleTest.cpp b/third_party/WebKit/Source/core/editing/EditingStyleTest.cpp
new file mode 100644
index 0000000..1e08e2e
--- /dev/null
+++ b/third_party/WebKit/Source/core/editing/EditingStyleTest.cpp
@@ -0,0 +1,41 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/editing/EditingStyle.h"
+
+#include "core/css/StylePropertySet.h"
+#include "core/dom/Document.h"
+#include "core/editing/EditingTestBase.h"
+#include "core/html/HTMLBodyElement.h"
+#include "core/html/HTMLDivElement.h"
+#include "core/html/HTMLHeadElement.h"
+#include "core/html/HTMLHtmlElement.h"
+
+namespace blink {
+
+class EditingStyleTest : public EditingTestBase {
+};
+
+TEST_F(EditingStyleTest, mergeInlineStyleOfElement)
+{
+    setBodyContent(
+        "<span id=s1 style='--A:var(---B)'>1</span>"
+        "<span id=s2 style='float:var(--C)'>2</span>");
+    updateAllLifecyclePhases();
+
+    EditingStyle* editingStyle = EditingStyle::create(
+        toHTMLElement(document().getElementById("s2")));
+    editingStyle->mergeInlineStyleOfElement(
+        toHTMLElement(document().getElementById("s1")),
+        EditingStyle::OverrideValues);
+
+    EXPECT_FALSE(editingStyle->style()->hasProperty(CSSPropertyFloat))
+        << "Don't merge a property with unresolved value";
+    EXPECT_EQ(
+        "var(---B)",
+        editingStyle->style()->getPropertyValue(AtomicString("--A")))
+        << "Keep unresolved value on merging style";
+}
+
+} // namespace blink