static String cssPropertyName(const Identifier& propertyName, bool* hadPixelOrPosPrefix = 0) { if (hadPixelOrPosPrefix) *hadPixelOrPosPrefix = false; unsigned length = propertyName.length(); if (!length) return String(); StringImpl* propertyNameString = propertyName.impl(); // If there is no uppercase character in the propertyName, there can // be no prefix, nor extension and we can return the same string. if (!containsASCIIUpperChar(*propertyNameString)) return String(propertyNameString); StringBuilder builder; builder.reserveCapacity(length); unsigned i = 0; switch (getCSSPropertyNamePrefix(*propertyNameString)) { case PropertyNamePrefixNone: if (isASCIIUpper((*propertyNameString)[0])) return String(); break; case PropertyNamePrefixCSS: i += 3; break; case PropertyNamePrefixPixel: i += 5; if (hadPixelOrPosPrefix) *hadPixelOrPosPrefix = true; break; case PropertyNamePrefixPos: i += 3; if (hadPixelOrPosPrefix) *hadPixelOrPosPrefix = true; break; case PropertyNamePrefixApple: case PropertyNamePrefixEpub: case PropertyNamePrefixKHTML: case PropertyNamePrefixWebKit: builder.append('-'); } builder.append(toASCIILower((*propertyNameString)[i++])); for (; i < length; ++i) { UChar c = (*propertyNameString)[i]; if (!isASCIIUpper(c)) builder.append(c); else builder.append(makeString('-', toASCIILower(c))); } return builder.toString(); }
static CSSPropertyInfo cssPropertyIDForJSCSSPropertyName(PropertyName propertyName) { CSSPropertyInfo propertyInfo = {CSSPropertyInvalid, false}; bool hadPixelOrPosPrefix = false; StringImpl* propertyNameString = propertyName.publicName(); if (!propertyNameString) return propertyInfo; unsigned length = propertyNameString->length(); if (!length) return propertyInfo; String stringForCache = String(propertyNameString); typedef HashMap<String, CSSPropertyInfo> CSSPropertyInfoMap; static NeverDestroyed<CSSPropertyInfoMap> propertyInfoCache; propertyInfo = propertyInfoCache.get().get(stringForCache); if (propertyInfo.propertyID) return propertyInfo; const size_t bufferSize = maxCSSPropertyNameLength + 1; char buffer[bufferSize]; char* bufferPtr = buffer; const char* name = bufferPtr; unsigned i = 0; // Prefixes CSS, Pixel, Pos are ignored. // Prefixes Apple, KHTML and Webkit are transposed to "-webkit-". // The prefix "Epub" becomes "-epub-". switch (getCSSPropertyNamePrefix(*propertyNameString)) { case PropertyNamePrefixNone: if (isASCIIUpper((*propertyNameString)[0])) return propertyInfo; break; case PropertyNamePrefixCSS: i += 3; break; case PropertyNamePrefixPixel: i += 5; hadPixelOrPosPrefix = true; break; case PropertyNamePrefixPos: i += 3; hadPixelOrPosPrefix = true; break; #if ENABLE(LEGACY_CSS_VENDOR_PREFIXES) case PropertyNamePrefixApple: case PropertyNamePrefixKHTML: ASSERT(RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled()); writeWebKitPrefix(bufferPtr); i += 5; break; #endif case PropertyNamePrefixEpub: writeEpubPrefix(bufferPtr); i += 4; break; case PropertyNamePrefixWebKit: writeWebKitPrefix(bufferPtr); i += 6; break; } *bufferPtr++ = toASCIILower((*propertyNameString)[i++]); char* bufferEnd = buffer + bufferSize; char* stringEnd = bufferEnd - 1; size_t bufferSizeLeft = stringEnd - bufferPtr; size_t propertySizeLeft = length - i; if (propertySizeLeft > bufferSizeLeft) return propertyInfo; for (; i < length; ++i) { UChar c = (*propertyNameString)[i]; if (!c || c >= 0x7F) return propertyInfo; // illegal character if (isASCIIUpper(c)) { size_t bufferSizeLeft = stringEnd - bufferPtr; size_t propertySizeLeft = length - i + 1; if (propertySizeLeft > bufferSizeLeft) return propertyInfo; *bufferPtr++ = '-'; *bufferPtr++ = toASCIILower(c); } else *bufferPtr++ = c; ASSERT_WITH_SECURITY_IMPLICATION(bufferPtr < bufferEnd); } ASSERT_WITH_SECURITY_IMPLICATION(bufferPtr < bufferEnd); *bufferPtr = '\0'; unsigned outputLength = bufferPtr - buffer; #if PLATFORM(IOS) cssPropertyNameIOSAliasing(buffer, name, outputLength); #endif const Property* hashTableEntry = findProperty(name, outputLength); int propertyID = hashTableEntry ? hashTableEntry->id : 0; if (propertyID) { propertyInfo.hadPixelOrPosPrefix = hadPixelOrPosPrefix; propertyInfo.propertyID = static_cast<CSSPropertyID>(propertyID); propertyInfoCache.get().add(stringForCache, propertyInfo); } return propertyInfo; }