JSCSSStyleDeclarationCustom.cpp [plain text]
#include "config.h"
#include "JSCSSStyleDeclarationCustom.h"
#include "AtomicString.h"
#include "CSSPrimitiveValue.h"
#include "CSSStyleDeclaration.h"
#include "CSSValue.h"
#include "PlatformString.h"
#include <runtime/StringObjectThatMasqueradesAsUndefined.h>
#include <runtime/StringPrototype.h>
#include <wtf/ASCIICType.h>
using namespace JSC;
using namespace WTF;
namespace WebCore {
static bool hasCSSPropertyNamePrefix(const Identifier& propertyName, const char* prefix)
{
#ifndef NDEBUG
ASSERT(*prefix);
for (const char* p = prefix; *p; ++p)
ASSERT(isASCIILower(*p));
ASSERT(propertyName.size());
#endif
if (toASCIILower(propertyName.data()[0]) != prefix[0])
return false;
unsigned length = propertyName.size();
for (unsigned i = 1; i < length; ++i) {
if (!prefix[i])
return isASCIIUpper(propertyName.data()[i]);
if (propertyName.data()[i] != prefix[i])
return false;
}
return false;
}
static String cssPropertyName(const Identifier& propertyName, bool* hadPixelOrPosPrefix = 0)
{
if (hadPixelOrPosPrefix)
*hadPixelOrPosPrefix = false;
unsigned length = propertyName.size();
if (!length)
return String();
Vector<UChar> name;
name.reserveInitialCapacity(length);
unsigned i = 0;
if (hasCSSPropertyNamePrefix(propertyName, "css"))
i += 3;
else if (hasCSSPropertyNamePrefix(propertyName, "pixel")) {
i += 5;
if (hadPixelOrPosPrefix)
*hadPixelOrPosPrefix = true;
} else if (hasCSSPropertyNamePrefix(propertyName, "pos")) {
i += 3;
if (hadPixelOrPosPrefix)
*hadPixelOrPosPrefix = true;
} else if (hasCSSPropertyNamePrefix(propertyName, "webkit")
|| hasCSSPropertyNamePrefix(propertyName, "khtml")
|| hasCSSPropertyNamePrefix(propertyName, "apple"))
name.append('-');
else {
if (isASCIIUpper(propertyName.data()[0]))
return String();
}
name.append(toASCIILower(propertyName.data()[i++]));
for (; i < length; ++i) {
UChar c = propertyName.data()[i];
if (!isASCIIUpper(c))
name.append(c);
else {
name.append('-');
name.append(toASCIILower(c));
}
}
return String::adopt(name);
}
static bool isCSSPropertyName(const Identifier& propertyName)
{
return CSSStyleDeclaration::isPropertyName(cssPropertyName(propertyName));
}
bool JSCSSStyleDeclaration::canGetItemsForName(ExecState*, CSSStyleDeclaration*, const Identifier& propertyName)
{
return isCSSPropertyName(propertyName);
}
JSValuePtr JSCSSStyleDeclaration::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
JSCSSStyleDeclaration* thisObj = static_cast<JSCSSStyleDeclaration*>(asObject(slot.slotBase()));
bool pixelOrPos;
String prop = cssPropertyName(propertyName, &pixelOrPos);
RefPtr<CSSValue> v = thisObj->impl()->getPropertyCSSValue(prop);
if (v) {
if (pixelOrPos && v->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE)
return jsNumber(exec, static_pointer_cast<CSSPrimitiveValue>(v)->getFloatValue(CSSPrimitiveValue::CSS_PX));
return jsStringOrNull(exec, v->cssText());
}
if (propertyName == "filter")
return StringObjectThatMasqueradesAsUndefined::create(exec, thisObj->impl()->getPropertyValue(prop));
return jsString(exec, thisObj->impl()->getPropertyValue(prop));
}
bool JSCSSStyleDeclaration::customPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot&)
{
if (!isCSSPropertyName(propertyName))
return false;
bool pixelOrPos;
String prop = cssPropertyName(propertyName, &pixelOrPos);
String propValue = valueToStringWithNullCheck(exec, value);
if (pixelOrPos)
propValue += "px";
ExceptionCode ec = 0;
impl()->setProperty(prop, propValue, ec);
setDOMException(exec, ec);
return true;
}
}