OLD | NEW |
1 // Copyright 2013, Google Inc. | 1 // Copyright 2013, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 12 matching lines...) Expand all Loading... |
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 |
30 #include "config.h" | 30 #include "config.h" |
31 #include "DartCSSStyleDeclaration.h" | 31 #include "DartCSSStyleDeclaration.h" |
32 | 32 |
| 33 #include "CSSPropertyNames.h" |
| 34 #include "core/css/CSSPrimitiveValue.h" |
| 35 #include "core/css/CSSStyleDeclaration.h" |
| 36 #include "core/css/CSSValue.h" |
| 37 #include "core/css/RuntimeCSSEnabled.h" |
| 38 #include "core/css/parser/BisonCSSParser.h" |
| 39 #include "wtf/ASCIICType.h" |
| 40 #include "wtf/PassRefPtr.h" |
| 41 #include "wtf/RefPtr.h" |
| 42 #include "wtf/StdLibExtras.h" |
| 43 #include "wtf/Vector.h" |
| 44 #include "wtf/text/StringBuilder.h" |
| 45 #include "wtf/text/StringConcatenate.h" |
| 46 |
| 47 using namespace WTF; |
| 48 using namespace std; |
| 49 |
33 namespace WebCore { | 50 namespace WebCore { |
34 | 51 |
| 52 struct CSSPropertyInfo { |
| 53 CSSPropertyID propID; |
| 54 }; |
| 55 |
35 namespace DartCSSStyleDeclarationInternal { | 56 namespace DartCSSStyleDeclarationInternal { |
36 | 57 |
37 void __setter__Callback(Dart_NativeArguments) | 58 void __setter__Callback(Dart_NativeArguments) |
38 { | 59 { |
39 // FIXME: proper implementation. | 60 // FIXME: proper implementation. |
40 DART_UNIMPLEMENTED(); | 61 DART_UNIMPLEMENTED(); |
41 } | 62 } |
42 | 63 |
| 64 static bool hasCSSPropertyNamePrefix(const String& propertyName, const char* pre
fix) |
| 65 { |
| 66 #ifndef NDEBUG |
| 67 ASSERT(*prefix); |
| 68 for (const char* p = prefix; *p; ++p) |
| 69 ASSERT(isASCIILower(*p)); |
| 70 ASSERT(propertyName.length()); |
| 71 #endif |
| 72 |
| 73 if (toASCIILower(propertyName[0]) != prefix[0]) |
| 74 return false; |
| 75 |
| 76 unsigned length = propertyName.length(); |
| 77 for (unsigned i = 1; i < length; ++i) { |
| 78 if (!prefix[i]) |
| 79 return isASCIIUpper(propertyName[i]); |
| 80 if (propertyName[i] != prefix[i]) |
| 81 return false; |
| 82 } |
| 83 return false; |
| 84 } |
| 85 |
| 86 static CSSPropertyID cssResolvedPropertyID(const String& propertyName) |
| 87 { |
| 88 unsigned length = propertyName.length(); |
| 89 if (!length) |
| 90 return CSSPropertyInvalid; |
| 91 |
| 92 StringBuilder builder; |
| 93 builder.reserveCapacity(length); |
| 94 |
| 95 unsigned i = 0; |
| 96 bool hasSeenDash = false; |
| 97 |
| 98 if (hasCSSPropertyNamePrefix(propertyName, "css")) |
| 99 i += 3; |
| 100 else if (hasCSSPropertyNamePrefix(propertyName, "webkit")) |
| 101 builder.append('-'); |
| 102 else if (isASCIIUpper(propertyName[0])) |
| 103 return CSSPropertyInvalid; |
| 104 |
| 105 bool hasSeenUpper = isASCIIUpper(propertyName[i]); |
| 106 |
| 107 builder.append(toASCIILower(propertyName[i++])); |
| 108 |
| 109 for (; i < length; ++i) { |
| 110 UChar c = propertyName[i]; |
| 111 if (!isASCIIUpper(c)) { |
| 112 if (c == '-') |
| 113 hasSeenDash = true; |
| 114 builder.append(c); |
| 115 } else { |
| 116 hasSeenUpper = true; |
| 117 builder.append('-'); |
| 118 builder.append(toASCIILower(c)); |
| 119 } |
| 120 } |
| 121 |
| 122 // Reject names containing both dashes and upper-case characters, such as "b
order-rightColor". |
| 123 if (hasSeenDash && hasSeenUpper) |
| 124 return CSSPropertyInvalid; |
| 125 |
| 126 String propName = builder.toString(); |
| 127 return cssPropertyID(propName); |
| 128 } |
| 129 |
| 130 // When getting properties on CSSStyleDeclarations, the name used from |
| 131 // Javascript and the actual name of the property are not the same, so |
| 132 // we have to do the following translation. The translation turns upper |
| 133 // case characters into lower case characters and inserts dashes to |
| 134 // separate words. |
| 135 // |
| 136 // Example: 'backgroundPositionY' -> 'background-position-y' |
| 137 // |
| 138 // Also, certain prefixes such as 'css-' are stripped. |
| 139 static CSSPropertyInfo* cssPropertyInfo(const String& propertyName) |
| 140 { |
| 141 typedef HashMap<String, CSSPropertyInfo*> CSSPropertyInfoMap; |
| 142 DEFINE_STATIC_LOCAL(CSSPropertyInfoMap, map, ()); |
| 143 CSSPropertyInfo* propInfo = map.get(propertyName); |
| 144 if (!propInfo) { |
| 145 propInfo = new CSSPropertyInfo(); |
| 146 propInfo->propID = cssResolvedPropertyID(propertyName); |
| 147 map.add(propertyName, propInfo); |
| 148 } |
| 149 if (propInfo->propID && RuntimeCSSEnabled::isCSSPropertyEnabled(propInfo->pr
opID)) |
| 150 return propInfo; |
| 151 return 0; |
| 152 } |
| 153 |
| 154 void propertyQuery(Dart_NativeArguments args) |
| 155 { |
| 156 Dart_Handle exception = 0; |
| 157 { |
| 158 DartStringAdapter propertyName = DartUtilities::dartToString(args, 1, ex
ception); |
| 159 if (exception) |
| 160 goto fail; |
| 161 |
| 162 // NOTE: cssPropertyInfo lookups incur several mallocs. |
| 163 // Successful lookups have the same cost the first time, but are cached. |
| 164 if (cssPropertyInfo(propertyName)) { |
| 165 Dart_SetReturnValue(args, DartUtilities::boolToDart(true)); |
| 166 return; |
| 167 } |
| 168 } |
| 169 |
| 170 fail: |
| 171 Dart_ThrowException(exception); |
| 172 ASSERT_NOT_REACHED(); |
| 173 } |
| 174 |
43 } | 175 } |
44 | 176 |
45 } | 177 } |
OLD | NEW |