5
5
#include " inline_css_style_declaration.h"
6
6
#include < vector>
7
7
#include " core/dom/element.h"
8
+ #include " core/dom/mutation_observer_interest_group.h"
8
9
#include " core/executing_context.h"
9
10
#include " core/html/parser/html_parser.h"
10
11
#include " css_property_list.h"
12
+ #include " element_namespace_uris.h"
13
+ #include " html_names.h"
11
14
12
15
namespace webf {
13
16
@@ -52,6 +55,27 @@ static std::string parseJavaScriptCSSPropertyName(std::string& propertyName) {
52
55
return result;
53
56
}
54
57
58
+ static std::string convertCamelCaseToKebabCase (const std::string& propertyName) {
59
+ static std::unordered_map<std::string, std::string> propertyCache{};
60
+
61
+ if (propertyCache.count (propertyName) > 0 ) {
62
+ return propertyCache[propertyName];
63
+ }
64
+
65
+ std::string result;
66
+ for (char c : propertyName) {
67
+ if (std::isupper (c)) {
68
+ result += ' -' ;
69
+ result += std::tolower (c);
70
+ } else {
71
+ result += c;
72
+ }
73
+ }
74
+
75
+ propertyCache[propertyName] = result;
76
+ return result;
77
+ }
78
+
55
79
InlineCssStyleDeclaration* InlineCssStyleDeclaration::Create (ExecutingContext* context,
56
80
ExceptionState& exception_state) {
57
81
exception_state.ThrowException (context->ctx (), ErrorType::TypeError, " Illegal constructor." );
@@ -79,7 +103,10 @@ bool InlineCssStyleDeclaration::SetItem(const AtomicString& key,
79
103
}
80
104
81
105
std::string propertyName = key.ToStdString (ctx ());
82
- return InternalSetProperty (propertyName, value.ToLegacyDOMString (ctx ()));
106
+ bool success = InternalSetProperty (propertyName, value.ToLegacyDOMString (ctx ()));
107
+ if (success)
108
+ InlineStyleChanged ();
109
+ return success;
83
110
}
84
111
85
112
bool InlineCssStyleDeclaration::DeleteItem (const webf::AtomicString& key, webf::ExceptionState& exception_state) {
@@ -90,6 +117,10 @@ int64_t InlineCssStyleDeclaration::length() const {
90
117
return properties_.size ();
91
118
}
92
119
120
+ void InlineCssStyleDeclaration::Clear () {
121
+ InternalClearProperty ();
122
+ }
123
+
93
124
AtomicString InlineCssStyleDeclaration::getPropertyValue (const AtomicString& key, ExceptionState& exception_state) {
94
125
std::string propertyName = key.ToStdString (ctx ());
95
126
return InternalGetPropertyValue (propertyName);
@@ -99,7 +130,9 @@ void InlineCssStyleDeclaration::setProperty(const AtomicString& key,
99
130
const ScriptValue& value,
100
131
ExceptionState& exception_state) {
101
132
std::string propertyName = key.ToStdString (ctx ());
102
- InternalSetProperty (propertyName, value.ToLegacyDOMString (ctx ()));
133
+ bool success = InternalSetProperty (propertyName, value.ToLegacyDOMString (ctx ()));
134
+ if (success)
135
+ InlineStyleChanged ();
103
136
}
104
137
105
138
AtomicString InlineCssStyleDeclaration::removeProperty (const AtomicString& key, ExceptionState& exception_state) {
@@ -117,7 +150,7 @@ AtomicString InlineCssStyleDeclaration::cssText() const {
117
150
std::string result;
118
151
size_t index = 0 ;
119
152
for (auto & attr : properties_) {
120
- result += attr.first + " : " + attr.second .ToStdString (ctx ()) + " ;" ;
153
+ result += convertCamelCaseToKebabCase ( attr.first ) + " : " + attr.second .ToStdString (ctx ()) + " ;" ;
121
154
index ++;
122
155
if (index < properties_.size ()) {
123
156
result += " " ;
@@ -127,11 +160,12 @@ AtomicString InlineCssStyleDeclaration::cssText() const {
127
160
}
128
161
129
162
void InlineCssStyleDeclaration::setCssText (const webf::AtomicString& value, webf::ExceptionState& exception_state) {
130
- const std::string css_text = value. ToStdString ( ctx () );
131
- setCssText (css_text, exception_state );
163
+ SetCSSTextInternal (value );
164
+ InlineStyleChanged ( );
132
165
}
133
166
134
- void InlineCssStyleDeclaration::setCssText (const std::string& css_text, webf::ExceptionState& exception_state) {
167
+ void InlineCssStyleDeclaration::SetCSSTextInternal (const AtomicString& value) {
168
+ const std::string css_text = value.ToStdString (ctx ());
135
169
InternalClearProperty ();
136
170
137
171
std::vector<std::string> styles;
@@ -173,6 +207,24 @@ std::string InlineCssStyleDeclaration::ToString() const {
173
207
return s;
174
208
}
175
209
210
+ void InlineCssStyleDeclaration::InlineStyleChanged () {
211
+ assert (owner_element_->IsStyledElement ());
212
+
213
+ owner_element_->InvalidateStyleAttribute ();
214
+
215
+ if (std::shared_ptr<MutationObserverInterestGroup> recipients =
216
+ MutationObserverInterestGroup::CreateForAttributesMutation (*owner_element_, html_names::kStyleAttr )) {
217
+ AtomicString old_value = AtomicString::Null ();
218
+ if (owner_element_->attributes ()->hasAttribute (html_names::kStyleAttr , ASSERT_NO_EXCEPTION ())) {
219
+ old_value = owner_element_->attributes ()->getAttribute (html_names::kStyleAttr , ASSERT_NO_EXCEPTION ());
220
+ }
221
+
222
+ recipients->EnqueueMutationRecord (
223
+ MutationRecord::CreateAttributes (owner_element_, html_names::kStyleAttr , AtomicString::Null (), old_value));
224
+ owner_element_->SynchronizeStyleAttributeInternal ();
225
+ }
226
+ }
227
+
176
228
bool InlineCssStyleDeclaration::NamedPropertyQuery (const AtomicString& key, ExceptionState&) {
177
229
return cssPropertyList.count (key.ToStdString (ctx ())) > 0 ;
178
230
}
@@ -196,9 +248,11 @@ AtomicString InlineCssStyleDeclaration::InternalGetPropertyValue(std::string& na
196
248
bool InlineCssStyleDeclaration::InternalSetProperty (std::string& name, const AtomicString& value) {
197
249
name = parseJavaScriptCSSPropertyName (name);
198
250
if (properties_[name] == value) {
199
- return true ;
251
+ return false ;
200
252
}
201
253
254
+ AtomicString old_value = properties_[name];
255
+
202
256
properties_[name] = value;
203
257
204
258
std::unique_ptr<SharedNativeString> args_01 = stringToNativeString (name);
@@ -218,6 +272,8 @@ AtomicString InlineCssStyleDeclaration::InternalRemoveProperty(std::string& name
218
272
AtomicString return_value = properties_[name];
219
273
properties_.erase (name);
220
274
275
+ InlineStyleChanged ();
276
+
221
277
std::unique_ptr<SharedNativeString> args_01 = stringToNativeString (name);
222
278
GetExecutingContext ()->uiCommandBuffer ()->addCommand (UICommand::kSetStyle , std::move (args_01),
223
279
owner_element_->bindingObject (), nullptr );
0 commit comments