Chromium Code Reviews| 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 "core/css/CSSPropertyMetadata.h" | |
| 9 #include "core/css/parser/CSSParser.h" | |
| 10 #include "core/frame/UseCounter.h" | |
| 11 #include "wtf/text/WTFString.h" | |
| 12 | |
| 13 using namespace WTF; | |
| 14 | |
| 15 namespace blink { | |
| 16 | |
| 17 // Check for a CSS prefix. | |
| 18 // Passed prefix is all lowercase. | |
| 19 // First character of the prefix within the property name may be upper or lowerc ase. | |
| 20 // Other characters in the prefix within the property name must be lowercase. | |
| 21 // The prefix within the property name must be followed by a capital letter. | |
| 22 static bool hasCSSPropertyNamePrefix(const String& propertyName, const char* pre fix) | |
| 23 { | |
| 24 #if ENABLE(ASSERT) | |
| 25 ASSERT(*prefix); | |
| 26 for (const char* p = prefix; *p; ++p) | |
| 27 ASSERT(isASCIILower(*p)); | |
| 28 ASSERT(propertyName.length()); | |
| 29 #endif | |
| 30 | |
| 31 if (toASCIILower(propertyName[0]) != prefix[0]) | |
| 32 return false; | |
| 33 | |
| 34 unsigned length = propertyName.length(); | |
| 35 for (unsigned i = 1; i < length; ++i) { | |
| 36 if (!prefix[i]) | |
| 37 return isASCIIUpper(propertyName[i]); | |
| 38 if (propertyName[i] != prefix[i]) | |
| 39 return false; | |
| 40 } | |
| 41 return false; | |
| 42 } | |
| 43 | |
| 44 static CSSPropertyID parseCSSPropertyID(v8::Isolate* isolate, const String& prop ertyName) | |
| 45 { | |
| 46 unsigned length = propertyName.length(); | |
| 47 if (!length) | |
| 48 return CSSPropertyInvalid; | |
| 49 | |
| 50 StringBuilder builder; | |
| 51 builder.reserveCapacity(length); | |
| 52 | |
| 53 unsigned i = 0; | |
| 54 bool hasSeenDash = false; | |
| 55 | |
| 56 if (hasCSSPropertyNamePrefix(propertyName, "css")) { | |
| 57 i += 3; | |
| 58 // getComputedStyle(elem).cssX is a non-standard behaviour | |
| 59 // Measure this behaviour as CSSXGetComputedStyleQueries. | |
| 60 UseCounter::countIfNotPrivateScript(isolate, callingExecutionContext(iso late), UseCounter::CSSXGetComputedStyleQueries); | |
| 61 } else if (hasCSSPropertyNamePrefix(propertyName, "webkit")) { | |
| 62 builder.append('-'); | |
| 63 } else if (isASCIIUpper(propertyName[0])) { | |
| 64 return CSSPropertyInvalid; | |
| 65 } | |
| 66 | |
| 67 bool hasSeenUpper = isASCIIUpper(propertyName[i]); | |
| 68 | |
| 69 builder.append(toASCIILower(propertyName[i++])); | |
| 70 | |
| 71 for (; i < length; ++i) { | |
| 72 UChar c = propertyName[i]; | |
| 73 if (!isASCIIUpper(c)) { | |
| 74 if (c == '-') | |
| 75 hasSeenDash = true; | |
| 76 builder.append(c); | |
| 77 } else { | |
| 78 hasSeenUpper = true; | |
| 79 builder.append('-'); | |
| 80 builder.append(toASCIILower(c)); | |
| 81 } | |
| 82 } | |
| 83 | |
| 84 // Reject names containing both dashes and upper-case characters, such as "b order-rightColor". | |
| 85 if (hasSeenDash && hasSeenUpper) | |
| 86 return CSSPropertyInvalid; | |
| 87 | |
| 88 String propName = builder.toString(); | |
| 89 return unresolvedCSSPropertyID(propName); | |
| 90 } | |
| 91 | |
| 92 static CSSPropertyID cssPropertyInfo(const String& propertyName, v8::Isolate* is olate) | |
| 93 { | |
| 94 typedef HashMap<String, CSSPropertyID> CSSPropertyIDMap; | |
| 95 DEFINE_STATIC_LOCAL(CSSPropertyIDMap, map, ()); | |
| 96 CSSPropertyIDMap::iterator iter = map.find(propertyName); | |
| 97 if (iter != map.end()) | |
| 98 return iter->value; | |
| 99 | |
| 100 CSSPropertyID unresolvedProperty = parseCSSPropertyID(isolate, propertyName) ; | |
| 101 map.add(propertyName, unresolvedProperty); | |
| 102 ASSERT(!unresolvedProperty || CSSPropertyMetadata::isEnabledProperty(unresol vedProperty)); | |
| 103 return unresolvedProperty; | |
| 104 } | |
| 105 | |
| 106 void CSSStyleDeclaration::anonymousNamedGetter(ScriptState* scriptState, const A tomicString& name, StringOrFloat& result) | |
| 107 { | |
| 108 // Search the style declaration. | |
| 109 CSSPropertyID unresolvedProperty = cssPropertyInfo(name, scriptState->isolat e()); | |
| 110 | |
| 111 // Do not handle non-property names. | |
| 112 if (!unresolvedProperty) | |
| 113 return; | |
| 114 CSSPropertyID resolvedProperty = resolveCSSPropertyID(unresolvedProperty); | |
| 115 | |
| 116 RefPtrWillBeRawPtr<CSSValue> cssValue = getPropertyCSSValueInternal(resolved Property); | |
| 117 if (cssValue) { | |
| 118 result.setString(cssValue->cssText()); | |
|
haraken
2015/04/29 15:53:46
The previous code was using v8SetReturnValueString
| |
| 119 return; | |
| 120 } | |
| 121 | |
| 122 result.setString(getPropertyValueInternal(resolvedProperty)); | |
| 123 } | |
| 124 | |
| 125 bool CSSStyleDeclaration::anonymousNamedSetter(ScriptState* scriptState, const S tring& name, const String& propertyValue, ExceptionState& exceptionState) | |
| 126 { | |
| 127 CSSPropertyID unresolvedProperty = cssPropertyInfo(name, scriptState->isolat e()); | |
| 128 if (!unresolvedProperty) | |
| 129 return false; | |
| 130 | |
| 131 setPropertyInternal(unresolvedProperty, propertyValue, false, exceptionState ); | |
|
haraken
2015/04/29 15:53:45
Don't we need:
if (exceptionState.throwIfNeeded
Jens Widell
2015/04/30 13:14:13
We do not. It's the outermost layer's job to actua
| |
| 132 return true; | |
| 133 } | |
| 134 | |
| 135 bool CSSStyleDeclaration::namedPropertyQuery(ScriptState* scriptState, const Ato micString& name, ExceptionState&) | |
| 136 { | |
| 137 if (!name.length()) | |
|
haraken
2015/04/29 15:53:45
Did we have this check in the previous code?
| |
| 138 return false; | |
| 139 // NOTE: cssPropertyInfo lookups incur several mallocs. | |
| 140 // Successful lookups have the same cost the first time, but are cached. | |
| 141 return cssPropertyInfo(name, scriptState->isolate()); | |
|
haraken
2015/04/29 15:53:45
In the previous code, we're doing v8SetReturnValue
| |
| 142 } | |
| 143 | |
| 144 void CSSStyleDeclaration::namedPropertyEnumerator(Vector<String>& names, Excepti onState&) | |
| 145 { | |
| 146 typedef Vector<String, numCSSProperties - 1> PreAllocatedPropertyVector; | |
| 147 DEFINE_STATIC_LOCAL(PreAllocatedPropertyVector, propertyNames, ()); | |
| 148 static unsigned propertyNamesLength = 0; | |
| 149 | |
| 150 if (propertyNames.isEmpty()) { | |
| 151 for (int id = firstCSSProperty; id <= lastCSSProperty; ++id) { | |
| 152 CSSPropertyID propertyId = static_cast<CSSPropertyID>(id); | |
| 153 if (CSSPropertyMetadata::isEnabledProperty(propertyId)) | |
| 154 propertyNames.append(getJSPropertyName(propertyId)); | |
| 155 } | |
| 156 std::sort(propertyNames.begin(), propertyNames.end(), codePointCompareLe ssThan); | |
| 157 propertyNamesLength = propertyNames.size(); | |
| 158 } | |
| 159 | |
| 160 for (unsigned i = 0; i < propertyNamesLength; ++i) { | |
| 161 String key = propertyNames.at(i); | |
| 162 ASSERT(!key.isNull()); | |
| 163 names.append(key); | |
| 164 } | |
| 165 } | |
| 166 | |
| 167 } | |
|
haraken
2015/04/29 15:53:45
// namespace blink
| |
| OLD | NEW |