OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "config.h" | |
6 #include "core/css/CSSStyleDeclaration.h" | |
7 | |
8 #include "bindings/core/v8/V8Binding.h" | |
9 #include "core/css/CSSPropertyMetadata.h" | |
10 #include "core/css/parser/CSSParser.h" | |
11 #include "core/frame/UseCounter.h" | |
12 #include "wtf/text/WTFString.h" | |
13 | |
14 using namespace WTF; | |
15 | |
16 namespace blink { | |
17 | |
18 // Check for a CSS prefix. | |
19 // Passed prefix is all lowercase. | |
20 // First character of the prefix within the property name may be upper or lowerc ase. | |
21 // Other characters in the prefix within the property name must be lowercase. | |
22 // The prefix within the property name must be followed by a capital letter. | |
23 static bool hasCSSPropertyNamePrefix(const String& propertyName, const char* pre fix) | |
24 { | |
25 #if ENABLE(ASSERT) | |
26 ASSERT(*prefix); | |
27 for (const char* p = prefix; *p; ++p) | |
28 ASSERT(isASCIILower(*p)); | |
29 ASSERT(propertyName.length()); | |
30 #endif | |
31 | |
32 if (toASCIILower(propertyName[0]) != prefix[0]) | |
33 return false; | |
34 | |
35 unsigned length = propertyName.length(); | |
36 for (unsigned i = 1; i < length; ++i) { | |
37 if (!prefix[i]) | |
38 return isASCIIUpper(propertyName[i]); | |
39 if (propertyName[i] != prefix[i]) | |
40 return false; | |
41 } | |
42 return false; | |
43 } | |
44 | |
45 static CSSPropertyID parseCSSPropertyID(v8::Isolate* isolate, const String& prop ertyName) | |
46 { | |
47 unsigned length = propertyName.length(); | |
48 if (!length) | |
49 return CSSPropertyInvalid; | |
50 | |
51 StringBuilder builder; | |
52 builder.reserveCapacity(length); | |
53 | |
54 unsigned i = 0; | |
55 bool hasSeenDash = false; | |
56 | |
57 if (hasCSSPropertyNamePrefix(propertyName, "css")) { | |
58 i += 3; | |
59 // getComputedStyle(elem).cssX is a non-standard behaviour | |
60 // Measure this behaviour as CSSXGetComputedStyleQueries. | |
61 UseCounter::countIfNotPrivateScript(isolate, callingExecutionContext(iso late), UseCounter::CSSXGetComputedStyleQueries); | |
62 } else if (hasCSSPropertyNamePrefix(propertyName, "webkit")) { | |
63 builder.append('-'); | |
64 } else if (isASCIIUpper(propertyName[0])) { | |
65 return CSSPropertyInvalid; | |
66 } | |
67 | |
68 bool hasSeenUpper = isASCIIUpper(propertyName[i]); | |
69 | |
70 builder.append(toASCIILower(propertyName[i++])); | |
71 | |
72 for (; i < length; ++i) { | |
73 UChar c = propertyName[i]; | |
74 if (!isASCIIUpper(c)) { | |
75 if (c == '-') | |
76 hasSeenDash = true; | |
77 builder.append(c); | |
78 } else { | |
79 hasSeenUpper = true; | |
80 builder.append('-'); | |
81 builder.append(toASCIILower(c)); | |
82 } | |
83 } | |
84 | |
85 // Reject names containing both dashes and upper-case characters, such as "b order-rightColor". | |
86 if (hasSeenDash && hasSeenUpper) | |
87 return CSSPropertyInvalid; | |
88 | |
89 String propName = builder.toString(); | |
90 return unresolvedCSSPropertyID(propName); | |
91 } | |
92 | |
93 // When getting properties on CSSStyleDeclarations, the name used from | |
94 // Javascript and the actual name of the property are not the same, so | |
95 // we have to do the following translation. The translation turns upper | |
96 // case characters into lower case characters and inserts dashes to | |
97 // separate words. | |
98 // | |
99 // Example: 'backgroundPositionY' -> 'background-position-y' | |
100 // | |
101 // Also, certain prefixes such as 'css-' are stripped. | |
102 static CSSPropertyID cssPropertyInfo(const String& propertyName, v8::Isolate* is olate) | |
vivekg
2015/04/30 05:24:03
Done.
vivekg
2015/04/30 05:24:03
Done.
| |
103 { | |
104 typedef HashMap<String, CSSPropertyID> CSSPropertyIDMap; | |
105 DEFINE_STATIC_LOCAL(CSSPropertyIDMap, map, ()); | |
106 CSSPropertyIDMap::iterator iter = map.find(propertyName); | |
107 if (iter != map.end()) | |
108 return iter->value; | |
109 | |
110 CSSPropertyID unresolvedProperty = parseCSSPropertyID(isolate, propertyName) ; | |
111 map.add(propertyName, unresolvedProperty); | |
112 ASSERT(!unresolvedProperty || CSSPropertyMetadata::isEnabledProperty(unresol vedProperty)); | |
113 return unresolvedProperty; | |
114 } | |
115 | |
116 bool CSSStyleDeclaration::anonymousNamedSetter(ScriptState* scriptState, const S tring& name, const String& propertyValue, ExceptionState& exceptionState) | |
117 { | |
118 CSSPropertyID unresolvedProperty = cssPropertyInfo(name, scriptState->isolat e()); | |
119 if (!unresolvedProperty) | |
120 return false; | |
121 | |
122 setPropertyInternal(unresolvedProperty, propertyValue, false, exceptionState ); | |
123 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
| |
124 return false; | |
125 return true; | |
126 } | |
127 | |
128 } | |
OLD | NEW |