WebKit does not enumerate over CSS properties in HTMLElement.style
https://bugs.webkit.org/show_bug.cgi?id=23946
Reviewed by Darin Adler.
Source/JavaScriptCore:
Add a few exports to follow the JSCSSStyleDeclaration.cpp changes,
introduce an std::sort() comparator function.
* JavaScriptCore.exp:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
* wtf/text/WTFString.h:
(WTF::codePointCompareLessThan): Used by std::sort() to sort properties.
Source/WebCore:
This change generates a list of JavaScript mirrors of the CSS properties and allows to enumerate them
using the "in" operator on the CSSStyleDeclaration object.
Test: fast/css/style-enumerate-properties.html
* bindings/js/JSCSSStyleDeclarationCustom.cpp:
(WebCore::JSCSSStyleDeclaration::getOwnPropertyNames): Added.
* bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp:
(WebCore::V8CSSStyleDeclaration::namedPropertyEnumerator): Added.
(WebCore::V8CSSStyleDeclaration::namedPropertyQuery): Added.
(WebCore::V8CSSStyleDeclaration::namedPropertyGetter): A small drive-by optimization (local initialization moved down).
* css/CSSStyleDeclaration.idl: Use a custom property enumerator.
* css/makeprop.pl: Add a function to convert CSS property names into JS ones.
LayoutTests:
* fast/css/style-enumerate-properties-expected.txt: Added.
* fast/css/style-enumerate-properties.html: Added.
* fast/dom/domListEnumeration-expected.txt:
* fast/dom/script-tests/domListEnumeration.js:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@102578 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index d96cec0..57bf573 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2011-11-30 Alexander Pavlov <apavlov@chromium.org>
+
+ WebKit does not enumerate over CSS properties in HTMLElement.style
+ https://bugs.webkit.org/show_bug.cgi?id=23946
+
+ Reviewed by Darin Adler.
+
+ * fast/css/style-enumerate-properties-expected.txt: Added.
+ * fast/css/style-enumerate-properties.html: Added.
+ * fast/dom/domListEnumeration-expected.txt:
+ * fast/dom/script-tests/domListEnumeration.js:
+
2011-12-12 Ilya Tikhonovsky <loislo@chromium.org>
Web Inspector: unreviewed test fix for r102574
diff --git a/LayoutTests/fast/dom/domListEnumeration-expected.txt b/LayoutTests/fast/dom/domListEnumeration-expected.txt
index 722ba07..9ca97ec 100644
--- a/LayoutTests/fast/dom/domListEnumeration-expected.txt
+++ b/LayoutTests/fast/dom/domListEnumeration-expected.txt
@@ -66,7 +66,6 @@
PASS resultArray[2].item is cssRuleList.item(2)
[object CSSStyleDeclaration]
-PASS resultArray.length is 14
PASS resultArray[0].i is '0'
PASS resultArray[0].item is cssStyleDeclaration.item(0)
PASS resultArray[1].i is '1'
diff --git a/LayoutTests/fast/dom/script-tests/domListEnumeration.js b/LayoutTests/fast/dom/script-tests/domListEnumeration.js
index a099c83..7a98755 100644
--- a/LayoutTests/fast/dom/script-tests/domListEnumeration.js
+++ b/LayoutTests/fast/dom/script-tests/domListEnumeration.js
@@ -173,7 +173,6 @@
//debug(escapeHTML(document.getElementsByTagName('style')));
var cssStyleDeclaration = document.styleSheets[2].cssRules[0].style;
resultArray = iterateList(cssStyleDeclaration);
-shouldBe("resultArray.length", "14");
shouldBe("resultArray[0].i", "'0'");
shouldBe("resultArray[0].item", "cssStyleDeclaration.item(0)");
shouldBe("resultArray[1].i", "'1'");
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 4f15ac5..480c509 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,18 @@
+2011-12-09 Alexander Pavlov <apavlov@chromium.org>
+
+ WebKit does not enumerate over CSS properties in HTMLElement.style
+ https://bugs.webkit.org/show_bug.cgi?id=23946
+
+ Reviewed by Darin Adler.
+
+ Add a few exports to follow the JSCSSStyleDeclaration.cpp changes,
+ introduce an std::sort() comparator function.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * wtf/text/WTFString.h:
+ (WTF::codePointCompareLessThan): Used by std::sort() to sort properties.
+
2011-12-12 Alexander Pavlov <apavlov@chromium.org>
Unreviewed, build fix.
diff --git a/Source/JavaScriptCore/JavaScriptCore.exp b/Source/JavaScriptCore/JavaScriptCore.exp
index 19885a4..b7e9364 100644
--- a/Source/JavaScriptCore/JavaScriptCore.exp
+++ b/Source/JavaScriptCore/JavaScriptCore.exp
@@ -155,6 +155,7 @@
__ZN3JSC12RegExpObjectC1EPNS_14JSGlobalObjectEPNS_9StructureEPNS_6RegExpE
__ZN3JSC12SamplingTool5setupEv
__ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
+__ZN3JSC12SmallStrings24singleCharacterStringRepEh
__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh
__ZN3JSC12StringObject14finishCreationERNS_12JSGlobalDataEPNS_8JSStringE
__ZN3JSC12StringObject6s_infoE
@@ -435,6 +436,7 @@
__ZN3WTF15charactersToIntEPKtmPb
__ZN3WTF16callOnMainThreadEPFvPvES0_
__ZN3WTF16codePointCompareERKNS_6StringES2_
+__ZN3WTF16codePointCompareEPKNS_10StringImplES2_
__ZN3WTF16fastZeroedMallocEm
__ZN3WTF17charactersToFloatEPKtmPbS2_
__ZN3WTF17equalIgnoringCaseEPKtPKhj
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index 6540179..ffd5a52 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -53,6 +53,7 @@
?activityCallback@Heap@JSC@@QAEPAVGCActivityCallback@2@XZ
?add@AtomicString@WTF@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@2@PBD@Z
?add@Identifier@JSC@@SA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVExecState@2@PBD@Z
+ ?add@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVJSGlobalData@2@PAVStringImpl@4@@Z
?add@PropertyNameArray@JSC@@QAEXPAVStringImpl@WTF@@@Z
?addBytes@MD5@WTF@@QAEXPBEI@Z
?addBytes@SHA1@WTF@@QAEXPBEI@Z
@@ -62,6 +63,7 @@
?addPropertyTransitionToExistingStructure@Structure@JSC@@SAPAV12@PAV12@ABVIdentifier@2@IPAVJSCell@2@AAI@Z
?addPropertyWithoutTransition@Structure@JSC@@QAEIAAVJSGlobalData@2@ABVIdentifier@2@IPAVJSCell@2@@Z
?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVExecState@2@PAVStringImpl@4@@Z
+ ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVJSGlobalData@2@PAVStringImpl@4@@Z
?addStaticGlobals@JSGlobalObject@JSC@@IAEXPAUGlobalPropertyInfo@12@H@Z
?allocatePropertyStorage@JSObject@JSC@@QAEXAAVJSGlobalData@2@II@Z
?allocateSlowCase@AllocationSpace@JSC@@AAEPAXAAUSizeClass@MarkedSpace@2@@Z
@@ -131,7 +133,7 @@
?currentThread@WTF@@YAIXZ
?currentThreadIsHoldingLock@JSLock@JSC@@SA_NXZ
?currentTime@WTF@@YANXZ
- ?execute@ParallelEnvironment@WTF@@QAEXPAX@Z
+ ?execute@ParallelEnvironment@WTF@@QAEXPAX@Z
?data@CString@WTF@@QBEPBDXZ
?dateToDaysFrom1970@WTF@@YANHHH@Z
?dayInMonthFromDayInYear@WTF@@YAHH_N@Z
@@ -313,6 +315,7 @@
?setter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ
?shrinkToFit@StringBuilder@WTF@@QAEXXZ
?signal@ThreadCondition@WTF@@QAEXXZ
+ ?singleCharacterStringRep@SmallStrings@JSC@@QAEPAVStringImpl@WTF@@E@Z
?size@Heap@JSC@@QAEIXZ
?slowAppend@MarkedArgumentBuffer@JSC@@AAEXVJSValue@2@@Z
?slowValidateCell@JSC@@YAXPAVJSCell@1@@Z
diff --git a/Source/JavaScriptCore/wtf/text/WTFString.h b/Source/JavaScriptCore/wtf/text/WTFString.h
index 7ffc7ec..e61b80f 100644
--- a/Source/JavaScriptCore/wtf/text/WTFString.h
+++ b/Source/JavaScriptCore/wtf/text/WTFString.h
@@ -506,6 +506,11 @@
WTF_EXPORT_PRIVATE int codePointCompare(const String&, const String&);
+inline bool codePointCompareLessThan(const String& a, const String& b)
+{
+ return codePointCompare(a.impl(), b.impl()) < 0;
+}
+
inline size_t find(const LChar* characters, unsigned length, LChar matchCharacter, unsigned index = 0)
{
while (index < length) {
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index b4093d4..38d9748 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,24 @@
+2011-11-25 Alexander Pavlov <apavlov@chromium.org>
+
+ WebKit does not enumerate over CSS properties in HTMLElement.style
+ https://bugs.webkit.org/show_bug.cgi?id=23946
+
+ Reviewed by Darin Adler.
+
+ This change generates a list of JavaScript mirrors of the CSS properties and allows to enumerate them
+ using the "in" operator on the CSSStyleDeclaration object.
+
+ Test: fast/css/style-enumerate-properties.html
+
+ * bindings/js/JSCSSStyleDeclarationCustom.cpp:
+ (WebCore::JSCSSStyleDeclaration::getOwnPropertyNames): Added.
+ * bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp:
+ (WebCore::V8CSSStyleDeclaration::namedPropertyEnumerator): Added.
+ (WebCore::V8CSSStyleDeclaration::namedPropertyQuery): Added.
+ (WebCore::V8CSSStyleDeclaration::namedPropertyGetter): A small drive-by optimization (local initialization moved down).
+ * css/CSSStyleDeclaration.idl: Use a custom property enumerator.
+ * css/makeprop.pl: Add a function to convert CSS property names into JS ones.
+
2011-12-12 Alexander Pavlov <apavlov@chromium.org>
Unreviewed, build fix.
diff --git a/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp b/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
index 2904e4b..affe0e0 100644
--- a/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
+++ b/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
@@ -28,6 +28,7 @@
#include "CSSMutableStyleDeclaration.h"
#include "CSSPrimitiveValue.h"
+#include "CSSPropertyNames.h"
#include "CSSValue.h"
#include "JSCSSValue.h"
#include "JSNode.h"
@@ -37,9 +38,11 @@
#include <wtf/text/AtomicString.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringConcatenate.h>
+#include <wtf/text/WTFString.h>
using namespace JSC;
using namespace WTF;
+using namespace std;
namespace WebCore {
@@ -139,8 +142,6 @@
return isCSSPropertyName(propertyName);
}
-// FIXME: You can get these properties, and set them (see putDelegate below),
-// but you should also be able to enumerate them.
JSValue JSCSSStyleDeclaration::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
JSCSSStyleDeclaration* thisObj = static_cast<JSCSSStyleDeclaration*>(asObject(slotBase));
@@ -195,4 +196,31 @@
return toJS(exec, globalObject(), WTF::getPtr(cssValue));
}
+void JSCSSStyleDeclaration::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+ JSCSSStyleDeclaration* thisObject = jsCast<JSCSSStyleDeclaration*>(object);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);
+
+ unsigned length = thisObject->impl()->length();
+ for (unsigned i = 0; i < length; ++i)
+ propertyNames.add(Identifier::from(exec, i));
+
+ static Identifier* propertyIdentifiers = 0;
+ if (!propertyIdentifiers) {
+ Vector<String, numCSSProperties> jsPropertyNames;
+ for (int id = firstCSSProperty; id < firstCSSProperty + numCSSProperties; ++id)
+ jsPropertyNames.append(getJSPropertyName(static_cast<CSSPropertyID>(id)));
+ sort(jsPropertyNames.begin(), jsPropertyNames.end(), WTF::codePointCompareLessThan);
+
+ propertyIdentifiers = new Identifier[numCSSProperties];
+ for (int i = 0; i < numCSSProperties; ++i)
+ propertyIdentifiers[i] = Identifier(exec, jsPropertyNames[i].impl());
+ }
+
+ for (int i = 0; i < numCSSProperties; ++i)
+ propertyNames.add(propertyIdentifiers[i]);
+
+ Base::getOwnPropertyNames(thisObject, exec, propertyNames, mode);
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp b/Source/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
index 643f0fe..b435b9b 100644
--- a/Source/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
+++ b/Source/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
@@ -32,6 +32,7 @@
#include "V8CSSStyleDeclaration.h"
#include "CSSParser.h"
+#include "CSSPropertyNames.h"
#include "CSSStyleDeclaration.h"
#include "CSSValue.h"
#include "CSSPrimitiveValue.h"
@@ -48,6 +49,9 @@
#include <wtf/StdLibExtras.h>
#include <wtf/Vector.h>
+using namespace WTF;
+using namespace std;
+
namespace WebCore {
// FIXME: Next two functions look lifted verbatim from JSCSSStyleDeclarationCustom. Please remove duplication.
@@ -152,6 +156,42 @@
return propInfo;
}
+v8::Handle<v8::Array> V8CSSStyleDeclaration::namedPropertyEnumerator(const v8::AccessorInfo& info)
+{
+ typedef Vector<String, numCSSProperties - 1> PreAllocatedPropertyVector;
+ DEFINE_STATIC_LOCAL(PreAllocatedPropertyVector, propertyNames, ());
+ DEFINE_STATIC_LOCAL(String, filterString, ("filter"));
+ static unsigned propertyNamesLength = 0;
+
+ if (propertyNames.isEmpty()) {
+ for (int id = firstCSSProperty; id < firstCSSProperty + numCSSProperties; ++id) {
+ String jsPropertyName = getJSPropertyName(static_cast<CSSPropertyID>(id));
+ // The "filter" property is present in the list but should not be provided in the enumeration.
+ // See a comment in the V8CSSStyleDeclaration::namedPropertyGetter() implementation.
+ // FIXME: this should be removed (see bug 73426).
+ if (jsPropertyName != filterString)
+ propertyNames.append(jsPropertyName);
+ }
+ sort(propertyNames.begin(), propertyNames.end(), codePointCompareLessThan);
+ propertyNamesLength = propertyNames.size();
+ }
+
+ v8::Handle<v8::Array> properties = v8::Array::New(propertyNamesLength);
+ for (unsigned i = 0; i < propertyNamesLength; ++i) {
+ String key = propertyNames.at(i);
+ ASSERT(!key.isNull());
+ properties->Set(v8::Integer::New(i), v8String(key));
+ }
+
+ return properties;
+}
+
+v8::Handle<v8::Integer> V8CSSStyleDeclaration::namedPropertyQuery(v8::Local<v8::String> v8Name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.CSSStyleDeclaration.NamedPropertyQuery");
+ return v8::Integer::New(v8::None);
+}
+
v8::Handle<v8::Value> V8CSSStyleDeclaration::namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
INC_STATS("DOM.CSSStyleDeclaration.NamedPropertyGetter");
@@ -160,14 +200,13 @@
return notHandledByInterceptor();
// Search the style declaration.
- CSSStyleDeclaration* imp = V8CSSStyleDeclaration::toNative(info.Holder());
CSSPropertyInfo* propInfo = cssPropertyInfo(name);
// Do not handle non-property names.
if (!propInfo)
return notHandledByInterceptor();
-
+ CSSStyleDeclaration* imp = V8CSSStyleDeclaration::toNative(info.Holder());
RefPtr<CSSValue> cssValue = imp->getPropertyCSSValue(propInfo->propID);
if (cssValue) {
if (propInfo->hadPixelOrPosPrefix &&
diff --git a/Source/WebCore/css/CSSStyleDeclaration.idl b/Source/WebCore/css/CSSStyleDeclaration.idl
index 2fa609b..d1b470f 100644
--- a/Source/WebCore/css/CSSStyleDeclaration.idl
+++ b/Source/WebCore/css/CSSStyleDeclaration.idl
@@ -27,6 +27,7 @@
DelegatingPutFunction,
HasNameGetter,
HasIndexGetter,
+ CustomGetPropertyNames,
V8DependentLifetime
] CSSStyleDeclaration {
attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString cssText
diff --git a/Source/WebCore/css/makeprop.pl b/Source/WebCore/css/makeprop.pl
index 45af713..7eff615 100644
--- a/Source/WebCore/css/makeprop.pl
+++ b/Source/WebCore/css/makeprop.pl
@@ -62,10 +62,14 @@
print GPERF << "EOF";
%{
/* This file is automatically generated from CSSPropertyNames.in by makeprop, do not edit */
+#include "config.h"
#include \"CSSPropertyNames.h\"
#include \"HashTools.h\"
#include <string.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/text/WTFString.h>
+
namespace WebCore {
%}
%struct-type
@@ -114,6 +118,28 @@
return propertyNameStrings[index];
}
+WTF::String getJSPropertyName(CSSPropertyID id)
+{
+ char result[maxCSSPropertyNameLength + 1];
+ const char* cssPropertyName = getPropertyName(id);
+ const char* propertyNamePointer = cssPropertyName;
+ if (!propertyNamePointer)
+ return emptyString();
+
+ char* resultPointer = result;
+ while (char character = *propertyNamePointer++) {
+ if (character == '-') {
+ char nextCharacter = *propertyNamePointer++;
+ if (!nextCharacter)
+ break;
+ character = (propertyNamePointer - 2 != cssPropertyName) ? toASCIIUpper(nextCharacter) : nextCharacter;
+ }
+ *resultPointer++ = character;
+ }
+ *resultPointer = '\\0';
+ return WTF::String(result);
+}
+
} // namespace WebCore
EOF
@@ -126,6 +152,10 @@
#include <string.h>
+namespace WTF {
+class String;
+}
+
namespace WebCore {
enum CSSPropertyID {
@@ -160,6 +190,7 @@
print HEADER << "EOF";
const char* getPropertyName(CSSPropertyID);
+WTF::String getJSPropertyName(CSSPropertyID);
} // namespace WebCore