Ignore:
Timestamp:
Nov 3, 2020, 10:45:53 AM (5 years ago)
Author:
[email protected]
Message:

Unreviewed, reverting r268564, r268957, and r268962.
https://bugs.webkit.org/show_bug.cgi?id=218525

Caused 9% binary size increase in WebCore

Reverted changesets:

"CSSStyleDeclaration breaks JS spec (properties not showing up
in Object.getOwnPropertyNames)"
https://bugs.webkit.org/show_bug.cgi?id=217623
https://trac.webkit.org/changeset/268564

"Remove support for 'pixel' and 'pos' CSSOM prefixes"
https://bugs.webkit.org/show_bug.cgi?id=119712
https://trac.webkit.org/changeset/268957

"Remove non-standard 'css'/'Css' prefixed properties on
CSSStyleDeclaration"
https://bugs.webkit.org/show_bug.cgi?id=218158
https://trac.webkit.org/changeset/268962

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/css/CSSStyleDeclaration.cpp

    r268962 r269314  
    3535#include "StyledElement.h"
    3636#include <wtf/IsoMallocInlines.h>
     37#include <wtf/Optional.h>
     38#include <wtf/Variant.h>
    3739
    3840namespace WebCore {
     
    4547    None,
    4648    Epub,
     49    CSS,
     50    Pixel,
     51    Pos,
    4752    WebKit
    4853};
    4954
    50 template<size_t prefixCStringLength> static inline bool matchesCSSPropertyNamePrefix(const StringImpl& propertyName, const char (&prefix)[prefixCStringLength])
     55template<size_t prefixCStringLength>
     56static inline bool matchesCSSPropertyNamePrefix(const StringImpl& propertyName, const char (&prefix)[prefixCStringLength])
    5157{
    5258    size_t prefixLength = prefixCStringLength - 1;
     
    8591    UChar firstChar = toASCIILower(propertyName[0]);
    8692    switch (firstChar) {
     93    case 'c':
     94        if (matchesCSSPropertyNamePrefix(propertyName, "css"))
     95            return PropertyNamePrefix::CSS;
     96        break;
    8797    case 'e':
    8898        if (matchesCSSPropertyNamePrefix(propertyName, "epub"))
    8999            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;
    90106        break;
    91107    case 'w':
     
    121137}
    122138
    123 static CSSPropertyID parseJavaScriptCSSPropertyName(const AtomString& propertyName)
    124 {
    125     using CSSPropertyIDMap = HashMap<String, CSSPropertyID>;
    126     static NeverDestroyed<CSSPropertyIDMap> propertyIDCache;
    127 
    128     CSSPropertyID propertyID = CSSPropertyInvalid;
     139struct CSSPropertyInfo {
     140    CSSPropertyID propertyID;
     141    bool hadPixelOrPosPrefix;
     142};
     143
     144static CSSPropertyInfo parseJavaScriptCSSPropertyName(const AtomString& propertyName)
     145{
     146    using CSSPropertyInfoMap = HashMap<String, CSSPropertyInfo>;
     147    static NeverDestroyed<CSSPropertyInfoMap> propertyInfoCache;
     148
     149    CSSPropertyInfo propertyInfo = { CSSPropertyInvalid, false };
    129150
    130151    auto* propertyNameString = propertyName.impl();
    131152    if (!propertyNameString)
    132         return propertyID;
     153        return propertyInfo;
    133154    unsigned length = propertyNameString->length();
    134155    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;
    140163
    141164    constexpr size_t bufferSize = maxCSSPropertyNameLength + 1;
     
    145168
    146169    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-".
    149173    switch (propertyNamePrefix(*propertyNameString)) {
    150174    case PropertyNamePrefix::None:
    151175        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;
    153188        break;
    154189    case PropertyNamePrefix::Epub:
     
    169204    size_t propertySizeLeft = length - i;
    170205    if (propertySizeLeft > bufferSizeLeft)
    171         return propertyID;
     206        return propertyInfo;
    172207
    173208    for (; i < length; ++i) {
    174209        UChar c = (*propertyNameString)[i];
    175210        if (!c || !isASCII(c))
    176             return propertyID; // illegal character
     211            return propertyInfo; // illegal character
    177212        if (isASCIIUpper(c)) {
    178213            size_t bufferSizeLeft = stringEnd - bufferPtr;
    179214            size_t propertySizeLeft = length - i + 1;
    180215            if (propertySizeLeft > bufferSizeLeft)
    181                 return propertyID;
     216                return propertyInfo;
    182217            *bufferPtr++ = '-';
    183218            *bufferPtr++ = toASCIILowerUnchecked(c);
     
    195230
    196231    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
     241static CSSPropertyInfo propertyInfoFromJavaScriptCSSPropertyName(const AtomString& propertyName, const Settings* settings)
     242{
     243    auto propertyInfo = parseJavaScriptCSSPropertyName(propertyName);
     244    auto id = propertyInfo.propertyID;
    207245    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
     252CSSPropertyID CSSStyleDeclaration::getCSSPropertyIDFromJavaScriptPropertyName(const AtomString& propertyName)
     253{
     254    return propertyInfoFromJavaScriptCSSPropertyName(propertyName, nullptr).propertyID;
     255}
     256
     257Optional<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
     280ExceptionOr<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
    216294    bool important = false;
    217295    if (DeprecatedGlobalSettings::shouldRespectPriorityInCSSAttributeSetters()) {
     
    223301    }
    224302
    225     auto setPropertyInternalResult = setPropertyInternal(propertyID, value, important);
     303    auto setPropertyInternalResult = setPropertyInternal(propertyInfo.propertyID, value, important);
    226304    if (setPropertyInternalResult.hasException())
    227305        return setPropertyInternalResult.releaseException();
     
    230308}
    231309
    232 CSSPropertyID CSSStyleDeclaration::getCSSPropertyIDFromJavaScriptPropertyName(const AtomString& propertyName)
    233 {
    234     return propertyIDFromJavaScriptCSSPropertyName(propertyName, nullptr);
     310Vector<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;
    235335}
    236336
Note: See TracChangeset for help on using the changeset viewer.