| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. 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 25 matching lines...) Expand all Loading... |
| 36 #include "core/css/CSSStyleSheet.h" | 36 #include "core/css/CSSStyleSheet.h" |
| 37 #include "core/css/CSSValue.h" | 37 #include "core/css/CSSValue.h" |
| 38 #include "core/dom/Document.h" | 38 #include "core/dom/Document.h" |
| 39 #include "core/dom/DocumentStyleSheetCollection.h" | 39 #include "core/dom/DocumentStyleSheetCollection.h" |
| 40 #include "core/dom/EventTarget.h" | 40 #include "core/dom/EventTarget.h" |
| 41 #include "core/html/HTMLStyleElement.h" | 41 #include "core/html/HTMLStyleElement.h" |
| 42 #include "core/page/RuntimeCSSEnabled.h" | 42 #include "core/page/RuntimeCSSEnabled.h" |
| 43 | 43 |
| 44 namespace WebCore { | 44 namespace WebCore { |
| 45 | 45 |
| 46 // FIXME: Next two functions look lifted verbatim from JSCSSStyleDeclarationCust
om. Please remove duplication. | |
| 47 | |
| 48 // Check for a CSS prefix. | |
| 49 // Passed prefix is all lowercase. | |
| 50 // First character of the prefix within the property name may be upper or lowerc
ase. | |
| 51 // Other characters in the prefix within the property name must be lowercase. | |
| 52 // The prefix within the property name must be followed by a capital letter. | |
| 53 static bool hasCSSPropertyNamePrefix(const String& propertyName, const char* pre
fix) | |
| 54 { | |
| 55 #ifndef NDEBUG | |
| 56 ASSERT(*prefix); | |
| 57 for (const char* p = prefix; *p; ++p) | |
| 58 ASSERT(isASCIILower(*p)); | |
| 59 ASSERT(propertyName.length()); | |
| 60 #endif | |
| 61 | |
| 62 if (toASCIILower(propertyName[0]) != prefix[0]) | |
| 63 return false; | |
| 64 | |
| 65 unsigned length = propertyName.length(); | |
| 66 for (unsigned i = 1; i < length; ++i) { | |
| 67 if (!prefix[i]) | |
| 68 return isASCIIUpper(propertyName[i]); | |
| 69 if (propertyName[i] != prefix[i]) | |
| 70 return false; | |
| 71 } | |
| 72 return false; | |
| 73 } | |
| 74 | |
| 75 // When getting properties on CSSStyleDeclarations, the name used from | |
| 76 // Javascript and the actual name of the property are not the same, so | |
| 77 // we have to do the following translation. The translation turns upper | |
| 78 // case characters into lower case characters and inserts dashes to | |
| 79 // separate words. | |
| 80 // | |
| 81 // Example: 'backgroundPositionY' -> 'background-position-y' | |
| 82 // | |
| 83 // Also, certain prefixes such as 'pos', 'css-' and 'pixel-' are stripped | |
| 84 // and the hadPixelOrPosPrefix out parameter is used to indicate whether or | |
| 85 // not the property name was prefixed with 'pos-' or 'pixel-'. | |
| 86 CSSPropertyInfo* CSSStyleDeclaration::cssPropertyInfo(const String& propertyName
) | |
| 87 { | |
| 88 typedef HashMap<String, CSSPropertyInfo*> CSSPropertyInfoMap; | |
| 89 DEFINE_STATIC_LOCAL(CSSPropertyInfoMap, map, ()); | |
| 90 CSSPropertyInfo* propInfo = map.get(propertyName); | |
| 91 if (!propInfo) { | |
| 92 unsigned length = propertyName.length(); | |
| 93 bool hadPixelOrPosPrefix = false; | |
| 94 if (!length) | |
| 95 return 0; | |
| 96 | |
| 97 StringBuilder builder; | |
| 98 builder.reserveCapacity(length); | |
| 99 | |
| 100 unsigned i = 0; | |
| 101 | |
| 102 if (hasCSSPropertyNamePrefix(propertyName, "css")) | |
| 103 i += 3; | |
| 104 else if (hasCSSPropertyNamePrefix(propertyName, "pixel")) { | |
| 105 i += 5; | |
| 106 hadPixelOrPosPrefix = true; | |
| 107 } else if (hasCSSPropertyNamePrefix(propertyName, "pos")) { | |
| 108 i += 3; | |
| 109 hadPixelOrPosPrefix = true; | |
| 110 } else if (hasCSSPropertyNamePrefix(propertyName, "webkit")) | |
| 111 builder.append('-'); | |
| 112 else if (isASCIIUpper(propertyName[0])) | |
| 113 return 0; | |
| 114 | |
| 115 builder.append(toASCIILower(propertyName[i++])); | |
| 116 | |
| 117 for (; i < length; ++i) { | |
| 118 UChar c = propertyName[i]; | |
| 119 if (!isASCIIUpper(c)) | |
| 120 builder.append(c); | |
| 121 else { | |
| 122 builder.append('-'); | |
| 123 builder.append(toASCIILower(c)); | |
| 124 } | |
| 125 } | |
| 126 | |
| 127 String propName = builder.toString(); | |
| 128 CSSPropertyID propertyID = cssPropertyID(propName); | |
| 129 if (propertyID && RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID)) { | |
| 130 propInfo = new CSSPropertyInfo(); | |
| 131 propInfo->hadPixelOrPosPrefix = hadPixelOrPosPrefix; | |
| 132 propInfo->propID = propertyID; | |
| 133 map.add(propertyName, propInfo); | |
| 134 } | |
| 135 } | |
| 136 return propInfo; | |
| 137 } | |
| 138 | |
| 139 void CSSStyleDeclaration::anonymousNamedGetter(const AtomicString& name, bool& r
eturnValue1Enabled, String& returnValue1, bool& returnValue2Enabled, float& retu
rnValue2) | |
| 140 { | |
| 141 // Search the style declaration. | |
| 142 CSSPropertyInfo* propInfo = cssPropertyInfo(name); | |
| 143 | |
| 144 // Do not handle non-property names. | |
| 145 if (!propInfo) | |
| 146 return; | |
| 147 | |
| 148 RefPtr<CSSValue> cssValue = getPropertyCSSValueInternal(static_cast<CSSPrope
rtyID>(propInfo->propID)); | |
| 149 if (cssValue) { | |
| 150 if (propInfo->hadPixelOrPosPrefix && cssValue->isPrimitiveValue()) { | |
| 151 returnValue2Enabled = true; | |
| 152 returnValue2 = static_cast<CSSPrimitiveValue*>(cssValue.get())->getF
loatValue(CSSPrimitiveValue::CSS_PX); | |
| 153 return; | |
| 154 } | |
| 155 returnValue1Enabled = true; | |
| 156 returnValue1 = cssValue->cssText(); | |
| 157 return; | |
| 158 } | |
| 159 | |
| 160 String result = getPropertyValueInternal(static_cast<CSSPropertyID>(propInfo
->propID)); | |
| 161 if (result.isNull()) | |
| 162 result = ""; // convert null to empty string. | |
| 163 | |
| 164 returnValue1 = result; | |
| 165 returnValue1Enabled = true; | |
| 166 } | |
| 167 | |
| 168 bool CSSStyleDeclaration::anonymousNamedSetter(const AtomicString& propertyName,
const String& value, ExceptionCode& ec) | |
| 169 { | |
| 170 String propertyValue = value; | |
| 171 CSSPropertyInfo* propInfo = CSSStyleDeclaration::cssPropertyInfo(propertyNam
e); | |
| 172 if (!propInfo) | |
| 173 return false; | |
| 174 | |
| 175 if (propInfo->hadPixelOrPosPrefix) | |
| 176 propertyValue.append("px"); | |
| 177 | |
| 178 this->setPropertyInternal(static_cast<CSSPropertyID>(propInfo->propID), prop
ertyValue, false, ec); | |
| 179 | |
| 180 return true; | |
| 181 } | |
| 182 | |
| 183 } // namespace WebCore | 46 } // namespace WebCore |
| OLD | NEW |