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 "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 |