Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(475)

Unified Diff: Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp

Issue 15914015: Make CSSStyleDeclaration getter/setter custom (Closed) Base URL: https://chromium.googlesource.com/chromium/blink@master
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | Source/core/css/CSSStyleDeclaration.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
diff --git a/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp b/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
index ae85a20d4c57ed1eaff1c1ac3a049872779e0712..6805ddd6912e986b96ef71dc3f6a324e5f762563 100644
--- a/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
+++ b/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
@@ -54,7 +54,105 @@ using namespace std;
namespace WebCore {
+// FIXME: Next two functions look lifted verbatim from JSCSSStyleDeclarationCustom. Please remove duplication.
+// Check for a CSS prefix.
+// Passed prefix is all lowercase.
+// First character of the prefix within the property name may be upper or lowercase.
+// Other characters in the prefix within the property name must be lowercase.
+// The prefix within the property name must be followed by a capital letter.
+static bool hasCSSPropertyNamePrefix(const String& propertyName, const char* prefix)
+{
+#ifndef NDEBUG
+ ASSERT(*prefix);
+ for (const char* p = prefix; *p; ++p)
+ ASSERT(isASCIILower(*p));
+ ASSERT(propertyName.length());
+#endif
+
+ if (toASCIILower(propertyName[0]) != prefix[0])
+ return false;
+
+ unsigned length = propertyName.length();
+ for (unsigned i = 1; i < length; ++i) {
+ if (!prefix[i])
+ return isASCIIUpper(propertyName[i]);
+ if (propertyName[i] != prefix[i])
+ return false;
+ }
+ return false;
+}
+
+class CSSPropertyInfo {
+public:
+ CSSPropertyID propID;
+ bool hadPixelOrPosPrefix;
+};
+
+// When getting properties on CSSStyleDeclarations, the name used from
+// Javascript and the actual name of the property are not the same, so
+// we have to do the following translation. The translation turns upper
+// case characters into lower case characters and inserts dashes to
+// separate words.
+//
+// Example: 'backgroundPositionY' -> 'background-position-y'
+//
+// Also, certain prefixes such as 'pos', 'css-' and 'pixel-' are stripped
+// and the hadPixelOrPosPrefix out parameter is used to indicate whether or
+// not the property name was prefixed with 'pos-' or 'pixel-'.
+static CSSPropertyInfo* cssPropertyInfo(v8::Handle<v8::String> v8PropertyName)
+{
+ String propertyName = toWebCoreString(v8PropertyName);
+ typedef HashMap<String, CSSPropertyInfo*> CSSPropertyInfoMap;
+ DEFINE_STATIC_LOCAL(CSSPropertyInfoMap, map, ());
+ CSSPropertyInfo* propInfo = map.get(propertyName);
+ if (!propInfo) {
+ unsigned length = propertyName.length();
+ bool hadPixelOrPosPrefix = false;
+ if (!length)
+ return 0;
+
+ StringBuilder builder;
+ builder.reserveCapacity(length);
+
+ unsigned i = 0;
+
+ if (hasCSSPropertyNamePrefix(propertyName, "css"))
+ i += 3;
+ else if (hasCSSPropertyNamePrefix(propertyName, "pixel")) {
+ i += 5;
+ hadPixelOrPosPrefix = true;
+ } else if (hasCSSPropertyNamePrefix(propertyName, "pos")) {
+ i += 3;
+ hadPixelOrPosPrefix = true;
+ } else if (hasCSSPropertyNamePrefix(propertyName, "webkit"))
+ builder.append('-');
+ else if (isASCIIUpper(propertyName[0]))
+ return 0;
+
+ builder.append(toASCIILower(propertyName[i++]));
+
+ for (; i < length; ++i) {
+ UChar c = propertyName[i];
+ if (!isASCIIUpper(c))
+ builder.append(c);
+ else {
+ builder.append('-');
+ builder.append(toASCIILower(c));
+ }
+ }
+
+ String propName = builder.toString();
+ CSSPropertyID propertyID = cssPropertyID(propName);
+ if (propertyID && RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID)) {
+ propInfo = new CSSPropertyInfo();
+ propInfo->hadPixelOrPosPrefix = hadPixelOrPosPrefix;
+ propInfo->propID = propertyID;
+ map.add(propertyName, propInfo);
+ }
+ }
+ return propInfo;
+}
v8::Handle<v8::Array> V8CSSStyleDeclaration::namedPropertyEnumerator(const v8::AccessorInfo& info)
{
@@ -86,11 +184,61 @@ v8::Handle<v8::Integer> V8CSSStyleDeclaration::namedPropertyQuery(v8::Local<v8::
{
// NOTE: cssPropertyInfo lookups incur several mallocs.
// Successful lookups have the same cost the first time, but are cached.
- String propertyName = toWebCoreString(v8Name);
- if (CSSStyleDeclaration::cssPropertyInfo(propertyName))
+ if (cssPropertyInfo(v8Name))
return v8Integer(0, info.GetIsolate());
return v8::Handle<v8::Integer>();
}
+v8::Handle<v8::Value> V8CSSStyleDeclaration::namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ // First look for API defined attributes on the style declaration object.
+ if (info.Holder()->HasRealNamedCallbackProperty(name))
+ return v8Undefined();
+
+ // Search the style declaration.
+ CSSPropertyInfo* propInfo = cssPropertyInfo(name);
+
+ // Do not handle non-property names.
+ if (!propInfo)
+ return v8Undefined();
+
+ CSSStyleDeclaration* imp = V8CSSStyleDeclaration::toNative(info.Holder());
+ RefPtr<CSSValue> cssValue = imp->getPropertyCSSValueInternal(static_cast<CSSPropertyID>(propInfo->propID));
+ if (cssValue) {
+ if (propInfo->hadPixelOrPosPrefix
+ && cssValue->isPrimitiveValue()) {
+ return v8::Number::New(static_cast<CSSPrimitiveValue*>(
+ cssValue.get())->getFloatValue(CSSPrimitiveValue::CSS_PX));
+ }
+ return v8StringOrNull(cssValue->cssText(), info.GetIsolate());
+ }
+
+ String result = imp->getPropertyValueInternal(static_cast<CSSPropertyID>(propInfo->propID));
+ if (result.isNull())
+ result = ""; // convert null to empty string.
+
+ return v8String(result, info.GetIsolate());
+}
+
+v8::Handle<v8::Value> V8CSSStyleDeclaration::namedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ CSSStyleDeclaration* imp = V8CSSStyleDeclaration::toNative(info.Holder());
+ CSSPropertyInfo* propInfo = cssPropertyInfo(name);
+ if (!propInfo)
+ return v8Undefined();
+
+ String propertyValue = toWebCoreStringWithNullCheck(value);
+ if (propInfo->hadPixelOrPosPrefix)
+ propertyValue.append("px");
+
+ ExceptionCode ec = 0;
+ imp->setPropertyInternal(static_cast<CSSPropertyID>(propInfo->propID), propertyValue, false, ec);
+
+ if (ec)
+ setDOMException(ec, info.GetIsolate());
+
+ return value;
+}
+
} // namespace WebCore
« no previous file with comments | « no previous file | Source/core/css/CSSStyleDeclaration.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698