Index: Source/core/css/CSSStyleDeclaration.cpp |
diff --git a/Source/core/css/CSSStyleDeclaration.cpp b/Source/core/css/CSSStyleDeclaration.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..712f2ddb0b4cfd7ca62dce3d5a76b7c2abed6402 |
--- /dev/null |
+++ b/Source/core/css/CSSStyleDeclaration.cpp |
@@ -0,0 +1,128 @@ |
+// Copyright (c) 2015 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 "config.h" |
+#include "core/css/CSSStyleDeclaration.h" |
+ |
+#include "bindings/core/v8/V8Binding.h" |
+#include "core/css/CSSPropertyMetadata.h" |
+#include "core/css/parser/CSSParser.h" |
+#include "core/frame/UseCounter.h" |
+#include "wtf/text/WTFString.h" |
+ |
+using namespace WTF; |
+ |
+namespace blink { |
+ |
+// Check for a CSS prefix. |
+// Passed prefix is all lowercase. |
+// First character of the prefix within the property name may be upper or lowercase. |
+// Other characters in the prefix within the property name must be lowercase. |
+// The prefix within the property name must be followed by a capital letter. |
+static bool hasCSSPropertyNamePrefix(const String& propertyName, const char* prefix) |
+{ |
+#if ENABLE(ASSERT) |
+ ASSERT(*prefix); |
+ for (const char* p = prefix; *p; ++p) |
+ ASSERT(isASCIILower(*p)); |
+ ASSERT(propertyName.length()); |
+#endif |
+ |
+ if (toASCIILower(propertyName[0]) != prefix[0]) |
+ return false; |
+ |
+ unsigned length = propertyName.length(); |
+ for (unsigned i = 1; i < length; ++i) { |
+ if (!prefix[i]) |
+ return isASCIIUpper(propertyName[i]); |
+ if (propertyName[i] != prefix[i]) |
+ return false; |
+ } |
+ return false; |
+} |
+ |
+static CSSPropertyID parseCSSPropertyID(v8::Isolate* isolate, const String& propertyName) |
+{ |
+ unsigned length = propertyName.length(); |
+ if (!length) |
+ return CSSPropertyInvalid; |
+ |
+ StringBuilder builder; |
+ builder.reserveCapacity(length); |
+ |
+ unsigned i = 0; |
+ bool hasSeenDash = false; |
+ |
+ if (hasCSSPropertyNamePrefix(propertyName, "css")) { |
+ i += 3; |
+ // getComputedStyle(elem).cssX is a non-standard behaviour |
+ // Measure this behaviour as CSSXGetComputedStyleQueries. |
+ UseCounter::countIfNotPrivateScript(isolate, callingExecutionContext(isolate), UseCounter::CSSXGetComputedStyleQueries); |
+ } else if (hasCSSPropertyNamePrefix(propertyName, "webkit")) { |
+ builder.append('-'); |
+ } else if (isASCIIUpper(propertyName[0])) { |
+ return CSSPropertyInvalid; |
+ } |
+ |
+ bool hasSeenUpper = isASCIIUpper(propertyName[i]); |
+ |
+ builder.append(toASCIILower(propertyName[i++])); |
+ |
+ for (; i < length; ++i) { |
+ UChar c = propertyName[i]; |
+ if (!isASCIIUpper(c)) { |
+ if (c == '-') |
+ hasSeenDash = true; |
+ builder.append(c); |
+ } else { |
+ hasSeenUpper = true; |
+ builder.append('-'); |
+ builder.append(toASCIILower(c)); |
+ } |
+ } |
+ |
+ // Reject names containing both dashes and upper-case characters, such as "border-rightColor". |
+ if (hasSeenDash && hasSeenUpper) |
+ return CSSPropertyInvalid; |
+ |
+ String propName = builder.toString(); |
+ return unresolvedCSSPropertyID(propName); |
+} |
+ |
+// When getting properties on CSSStyleDeclarations, the name used from |
+// Javascript and the actual name of the property are not the same, so |
+// we have to do the following translation. The translation turns upper |
+// case characters into lower case characters and inserts dashes to |
+// separate words. |
+// |
+// Example: 'backgroundPositionY' -> 'background-position-y' |
+// |
+// Also, certain prefixes such as 'css-' are stripped. |
+static CSSPropertyID cssPropertyInfo(const String& propertyName, v8::Isolate* isolate) |
vivekg
2015/04/30 05:24:03
Done.
vivekg
2015/04/30 05:24:03
Done.
|
+{ |
+ typedef HashMap<String, CSSPropertyID> CSSPropertyIDMap; |
+ DEFINE_STATIC_LOCAL(CSSPropertyIDMap, map, ()); |
+ CSSPropertyIDMap::iterator iter = map.find(propertyName); |
+ if (iter != map.end()) |
+ return iter->value; |
+ |
+ CSSPropertyID unresolvedProperty = parseCSSPropertyID(isolate, propertyName); |
+ map.add(propertyName, unresolvedProperty); |
+ ASSERT(!unresolvedProperty || CSSPropertyMetadata::isEnabledProperty(unresolvedProperty)); |
+ return unresolvedProperty; |
+} |
+ |
+bool CSSStyleDeclaration::anonymousNamedSetter(ScriptState* scriptState, const String& name, const String& propertyValue, ExceptionState& exceptionState) |
+{ |
+ CSSPropertyID unresolvedProperty = cssPropertyInfo(name, scriptState->isolate()); |
+ if (!unresolvedProperty) |
+ return false; |
+ |
+ setPropertyInternal(unresolvedProperty, propertyValue, false, exceptionState); |
+ if (exceptionState.throwIfNeeded()) |
vivekg
2015/04/30 05:24:03
Done.
haraken
2015/04/30 05:30:21
I noticed that exceptionState.throwIfNeeded() is c
|
+ return false; |
+ return true; |
+} |
+ |
+} |