Changeset 269314 in webkit for trunk/Source/WebCore/css/CSSStyleDeclaration.cpp
- Timestamp:
- Nov 3, 2020, 10:45:53 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/css/CSSStyleDeclaration.cpp
r268962 r269314 35 35 #include "StyledElement.h" 36 36 #include <wtf/IsoMallocInlines.h> 37 #include <wtf/Optional.h> 38 #include <wtf/Variant.h> 37 39 38 40 namespace WebCore { … … 45 47 None, 46 48 Epub, 49 CSS, 50 Pixel, 51 Pos, 47 52 WebKit 48 53 }; 49 54 50 template<size_t prefixCStringLength> static inline bool matchesCSSPropertyNamePrefix(const StringImpl& propertyName, const char (&prefix)[prefixCStringLength]) 55 template<size_t prefixCStringLength> 56 static inline bool matchesCSSPropertyNamePrefix(const StringImpl& propertyName, const char (&prefix)[prefixCStringLength]) 51 57 { 52 58 size_t prefixLength = prefixCStringLength - 1; … … 85 91 UChar firstChar = toASCIILower(propertyName[0]); 86 92 switch (firstChar) { 93 case 'c': 94 if (matchesCSSPropertyNamePrefix(propertyName, "css")) 95 return PropertyNamePrefix::CSS; 96 break; 87 97 case 'e': 88 98 if (matchesCSSPropertyNamePrefix(propertyName, "epub")) 89 99 return PropertyNamePrefix::Epub; 100 break; 101 case 'p': 102 if (matchesCSSPropertyNamePrefix(propertyName, "pos")) 103 return PropertyNamePrefix::Pos; 104 if (matchesCSSPropertyNamePrefix(propertyName, "pixel")) 105 return PropertyNamePrefix::Pixel; 90 106 break; 91 107 case 'w': … … 121 137 } 122 138 123 static CSSPropertyID parseJavaScriptCSSPropertyName(const AtomString& propertyName) 124 { 125 using CSSPropertyIDMap = HashMap<String, CSSPropertyID>; 126 static NeverDestroyed<CSSPropertyIDMap> propertyIDCache; 127 128 CSSPropertyID propertyID = CSSPropertyInvalid; 139 struct CSSPropertyInfo { 140 CSSPropertyID propertyID; 141 bool hadPixelOrPosPrefix; 142 }; 143 144 static CSSPropertyInfo parseJavaScriptCSSPropertyName(const AtomString& propertyName) 145 { 146 using CSSPropertyInfoMap = HashMap<String, CSSPropertyInfo>; 147 static NeverDestroyed<CSSPropertyInfoMap> propertyInfoCache; 148 149 CSSPropertyInfo propertyInfo = { CSSPropertyInvalid, false }; 129 150 130 151 auto* propertyNameString = propertyName.impl(); 131 152 if (!propertyNameString) 132 return propertyI D;153 return propertyInfo; 133 154 unsigned length = propertyNameString->length(); 134 155 if (!length) 135 return propertyID; 136 137 propertyID = propertyIDCache.get().get(propertyNameString); 138 if (propertyID) 139 return propertyID; 156 return propertyInfo; 157 158 propertyInfo = propertyInfoCache.get().get(propertyNameString); 159 if (propertyInfo.propertyID) 160 return propertyInfo; 161 162 bool hadPixelOrPosPrefix = false; 140 163 141 164 constexpr size_t bufferSize = maxCSSPropertyNameLength + 1; … … 145 168 146 169 unsigned i = 0; 147 // Prefix Webkit becomes "-webkit-". 148 // Prefix Epub becomes "-epub-". 170 // Prefixes CSS, Pixel, Pos are ignored. 171 // Prefixes Apple, KHTML and Webkit are transposed to "-webkit-". 172 // The prefix "Epub" becomes "-epub-". 149 173 switch (propertyNamePrefix(*propertyNameString)) { 150 174 case PropertyNamePrefix::None: 151 175 if (isASCIIUpper((*propertyNameString)[0])) 152 return propertyID; 176 return propertyInfo; 177 break; 178 case PropertyNamePrefix::CSS: 179 i += 3; 180 break; 181 case PropertyNamePrefix::Pixel: 182 i += 5; 183 hadPixelOrPosPrefix = true; 184 break; 185 case PropertyNamePrefix::Pos: 186 i += 3; 187 hadPixelOrPosPrefix = true; 153 188 break; 154 189 case PropertyNamePrefix::Epub: … … 169 204 size_t propertySizeLeft = length - i; 170 205 if (propertySizeLeft > bufferSizeLeft) 171 return propertyI D;206 return propertyInfo; 172 207 173 208 for (; i < length; ++i) { 174 209 UChar c = (*propertyNameString)[i]; 175 210 if (!c || !isASCII(c)) 176 return propertyI D; // illegal character211 return propertyInfo; // illegal character 177 212 if (isASCIIUpper(c)) { 178 213 size_t bufferSizeLeft = stringEnd - bufferPtr; 179 214 size_t propertySizeLeft = length - i + 1; 180 215 if (propertySizeLeft > bufferSizeLeft) 181 return propertyI D;216 return propertyInfo; 182 217 *bufferPtr++ = '-'; 183 218 *bufferPtr++ = toASCIILowerUnchecked(c); … … 195 230 196 231 auto* hashTableEntry = findProperty(name, outputLength); 197 if (auto id = hashTableEntry ? hashTableEntry->id : 0) { 198 propertyID = static_cast<CSSPropertyID>(id); 199 propertyIDCache.get().add(propertyNameString, propertyID); 200 } 201 return propertyID; 202 } 203 204 static CSSPropertyID propertyIDFromJavaScriptCSSPropertyName(const AtomString& propertyName, const Settings* settings) 205 { 206 auto id = parseJavaScriptCSSPropertyName(propertyName); 232 if (auto propertyID = hashTableEntry ? hashTableEntry->id : 0) { 233 auto id = static_cast<CSSPropertyID>(propertyID); 234 propertyInfo.hadPixelOrPosPrefix = hadPixelOrPosPrefix; 235 propertyInfo.propertyID = id; 236 propertyInfoCache.get().add(propertyNameString, propertyInfo); 237 } 238 return propertyInfo; 239 } 240 241 static CSSPropertyInfo propertyInfoFromJavaScriptCSSPropertyName(const AtomString& propertyName, const Settings* settings) 242 { 243 auto propertyInfo = parseJavaScriptCSSPropertyName(propertyName); 244 auto id = propertyInfo.propertyID; 207 245 if (!isEnabledCSSProperty(id) || !isCSSPropertyEnabledBySettings(id, settings)) 208 return CSSPropertyInvalid; 209 return id; 210 } 211 212 } 213 214 ExceptionOr<void> CSSStyleDeclaration::setPropertyValueInternal(CSSPropertyID propertyID, String value) 215 { 246 return { CSSPropertyInvalid, false }; 247 return propertyInfo; 248 } 249 250 } 251 252 CSSPropertyID CSSStyleDeclaration::getCSSPropertyIDFromJavaScriptPropertyName(const AtomString& propertyName) 253 { 254 return propertyInfoFromJavaScriptCSSPropertyName(propertyName, nullptr).propertyID; 255 } 256 257 Optional<Variant<String, double>> CSSStyleDeclaration::namedItem(const AtomString& propertyName) 258 { 259 auto* settings = parentElement() ? &parentElement()->document().settings() : nullptr; 260 auto propertyInfo = propertyInfoFromJavaScriptCSSPropertyName(propertyName, settings); 261 if (!propertyInfo.propertyID) 262 return WTF::nullopt; 263 264 auto value = getPropertyCSSValueInternal(propertyInfo.propertyID); 265 if (!value) { 266 // If the property is a shorthand property (such as "padding"), it can only be accessed using getPropertyValue. 267 return Variant<String, double> { getPropertyValueInternal(propertyInfo.propertyID) }; 268 } 269 270 if (propertyInfo.hadPixelOrPosPrefix && is<CSSPrimitiveValue>(*value)) { 271 // Call this version of the getter so that, e.g., pixelTop returns top as a number 272 // in pixel units and posTop should does the same _if_ this is a positioned element. 273 // FIXME: If not a positioned element, MSIE documentation says posTop should return 0; this rule is not implemented. 274 return Variant<String, double> { downcast<CSSPrimitiveValue>(*value).floatValue(CSSUnitType::CSS_PX) }; 275 } 276 277 return Variant<String, double> { value->cssText() }; 278 } 279 280 ExceptionOr<void> CSSStyleDeclaration::setNamedItem(const AtomString& propertyName, String value, bool& propertySupported) 281 { 282 auto* settings = parentElement() ? &parentElement()->document().settings() : nullptr; 283 auto propertyInfo = propertyInfoFromJavaScriptCSSPropertyName(propertyName, settings); 284 if (!propertyInfo.propertyID) { 285 propertySupported = false; 286 return { }; 287 } 288 289 propertySupported = true; 290 291 if (propertyInfo.hadPixelOrPosPrefix) 292 value.append("px"); 293 216 294 bool important = false; 217 295 if (DeprecatedGlobalSettings::shouldRespectPriorityInCSSAttributeSetters()) { … … 223 301 } 224 302 225 auto setPropertyInternalResult = setPropertyInternal(propertyI D, value, important);303 auto setPropertyInternalResult = setPropertyInternal(propertyInfo.propertyID, value, important); 226 304 if (setPropertyInternalResult.hasException()) 227 305 return setPropertyInternalResult.releaseException(); … … 230 308 } 231 309 232 CSSPropertyID CSSStyleDeclaration::getCSSPropertyIDFromJavaScriptPropertyName(const AtomString& propertyName) 233 { 234 return propertyIDFromJavaScriptCSSPropertyName(propertyName, nullptr); 310 Vector<AtomString> CSSStyleDeclaration::supportedPropertyNames() const 311 { 312 static unsigned numNames = 0; 313 static const AtomString* const cssPropertyNames = [] { 314 String names[numCSSProperties]; 315 for (int i = 0; i < numCSSProperties; ++i) { 316 CSSPropertyID id = static_cast<CSSPropertyID>(firstCSSProperty + i); 317 // FIXME: Should take account for flags in settings(). 318 if (isEnabledCSSProperty(id)) 319 names[numNames++] = getJSPropertyName(id); 320 } 321 std::sort(&names[0], &names[numNames], WTF::codePointCompareLessThan); 322 auto* identifiers = new AtomString[numNames]; 323 for (unsigned i = 0; i < numNames; ++i) 324 identifiers[i] = names[i]; 325 return identifiers; 326 }(); 327 328 Vector<AtomString> result; 329 result.reserveInitialCapacity(numNames); 330 331 for (unsigned i = 0; i < numNames; ++i) 332 result.uncheckedAppend(cssPropertyNames[i]); 333 334 return result; 235 335 } 236 336
Note:
See TracChangeset
for help on using the changeset viewer.