Diff
Modified: trunk/LayoutTests/ChangeLog (219621 => 219622)
--- trunk/LayoutTests/ChangeLog 2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/LayoutTests/ChangeLog 2017-07-18 20:12:15 UTC (rev 219622)
@@ -1,3 +1,14 @@
+2017-07-18 Sam Weinig <s...@webkit.org>
+
+ [WebIDL] Replace some custom bindings code in JSCSSStyleDeclarationCustom.cpp with named getters/setters
+ https://bugs.webkit.org/show_bug.cgi?id=174529
+
+ Reviewed by Chris Dumez.
+
+ * fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor-expected.txt:
+ * fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor.html:
+ Update test and result to match standard and other browsers.
+
2017-07-18 Matt Lewis <jlew...@apple.com>
Unreviewed, rolling out r219610.
Modified: trunk/LayoutTests/fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor-expected.txt (219621 => 219622)
--- trunk/LayoutTests/fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor-expected.txt 2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/LayoutTests/fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor-expected.txt 2017-07-18 20:12:15 UTC (rev 219622)
@@ -5,7 +5,7 @@
PASS descriptor['writable'] is true
PASS descriptor['enumerable'] is true
-PASS descriptor['configurable'] is false
+PASS descriptor['configurable'] is true
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor.html (219621 => 219622)
--- trunk/LayoutTests/fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor.html 2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/LayoutTests/fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor.html 2017-07-18 20:12:15 UTC (rev 219622)
@@ -8,7 +8,7 @@
var descriptor = Object.getOwnPropertyDescriptor(document.body.style, 'color');
shouldBeTrue("descriptor['writable']");
shouldBeTrue("descriptor['enumerable']");
- shouldBeFalse("descriptor['configurable']");
+ shouldBeTrue("descriptor['configurable']");
</script>
<script src=""
</body>
Modified: trunk/Source/WebCore/CMakeLists.txt (219621 => 219622)
--- trunk/Source/WebCore/CMakeLists.txt 2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/CMakeLists.txt 2017-07-18 20:12:15 UTC (rev 219622)
@@ -1356,6 +1356,7 @@
css/CSSSelector.cpp
css/CSSSelectorList.cpp
css/CSSShadowValue.cpp
+ css/CSSStyleDeclaration.cpp
css/CSSStyleRule.cpp
css/CSSStyleSheet.cpp
css/CSSSupportsRule.cpp
Modified: trunk/Source/WebCore/ChangeLog (219621 => 219622)
--- trunk/Source/WebCore/ChangeLog 2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/ChangeLog 2017-07-18 20:12:15 UTC (rev 219622)
@@ -1,3 +1,66 @@
+2017-07-18 Sam Weinig <s...@webkit.org>
+
+ [WebIDL] Replace some custom bindings code in JSCSSStyleDeclarationCustom.cpp with named getters/setters
+ https://bugs.webkit.org/show_bug.cgi?id=174529
+
+ Reviewed by Chris Dumez.
+
+ * CMakeLists.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * css/CSSAllInOne.cpp:
+ Add CSSStyleDeclaration.cpp
+
+ * bindings/js/JSCSSStyleDeclarationCustom.cpp:
+ Move getter / setter / getOwnProperties logic from here to CSSStyleDeclaration.cpp.
+
+ * bindings/scripts/CodeGeneratorJS.pm:
+ (GenerateGetOwnPropertySlot):
+ (GenerateGetOwnPropertySlotByIndex):
+ (InstanceOverridesGetOwnPropertySlot):
+ (GenerateHeader):
+ Remove support for no longer needed [CustomGetOwnPropertySlotAndDescriptor].
+ Add support for [PutOnlyForSupportedProperties], which allows named setters to behave
+ a bit more like normal setters by allowing the implementation to note which properties
+ are supported which in turn, allows the bindings to continue down the normal put path
+ for unsupported properties. This is necessary to mimic the behavior of CSSStyleDeclaration
+ which is using named setters in place hundreds of additional properties.
+
+ (InstanceOverridesDefineOwnProperty):
+ Add [DefaultDefineOwnProperty] to allow disabling defineOwnProperty overriding that comes
+ automatically with named setters. We need this for CSSStyleDeclaration since the named
+ setter usage modeling real properties, not a dictionary style setter. We may want to
+ revisit this, and add support for DefineOwnProperty here, but this allows us to maintain
+ the status quo.
+
+ (GenerateDefineOwnProperty):
+ Fix the case when you have a named setter, an indexed getter, but no indexed setter. In that
+ case, we would get a compile error, due to the index variable being unused.
+
+ * bindings/scripts/IDLAttributes.json:
+ Remove support for no longer needed [CustomGetOwnPropertySlotAndDescriptor], add
+ [PutOnlyForSupportedProperties] and [DefaultDefineOwnProperty].
+
+ * css/CSSStyleDeclaration.h:
+ * css/CSSStyleDeclaration.cpp: Added.
+ (WebCore::CSSStyleDeclaration::namedItem):
+ (WebCore::CSSStyleDeclaration::setNamedItem):
+ (WebCore::CSSStyleDeclaration::isSupportedPropertyName):
+ (WebCore::CSSStyleDeclaration::supportedPropertyNames):
+ Use standard getter / setter functions to implement CSS property name getting and setting.
+ Convert from Identifier to AtomicString, which are now bridgeable.
+
+ * css/CSSStyleDeclaration.idl:
+ Add named getter and setter. Remove [CustomGetOwnPropertyNames], [CustomGetOwnPropertySlotAndDescriptor]
+ and [CustomPut], add [DefaultDefineOwnProperty].
+
+ * bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp: Added.
+ * bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.h: Added.
+ * bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp: Added.
+ * bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.h: Added.
+ * bindings/scripts/test/TestNamedSetterWithIndexedGetter.idl: Added.
+ * bindings/scripts/test/TestNamedSetterWithIndexedGetterAndSetter.idl: Added.
+ Add tests for improved behavior when using named setters with variations of indexed getters and setters as well.
+
2017-07-18 Antoine Quint <grao...@apple.com>
[iOS] WebKit media controls are sometimes shown after exiting full screen on vimeo.com
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (219621 => 219622)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-07-18 20:12:15 UTC (rev 219622)
@@ -3281,6 +3281,7 @@
7CD0BA051B8F79C9005CEBBE /* ActiveDOMCallbackMicrotask.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CD0BA031B8F79C9005CEBBE /* ActiveDOMCallbackMicrotask.h */; };
7CD494CC1A86EB1D000A87EC /* RenderAttachment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CD494CA1A86EB1D000A87EC /* RenderAttachment.cpp */; };
7CD494CD1A86EB1D000A87EC /* RenderAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CD494CB1A86EB1D000A87EC /* RenderAttachment.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 7CDE8EBE1F193BCB00168FE7 /* CSSStyleDeclaration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CDE8EBC1F193BC500168FE7 /* CSSStyleDeclaration.cpp */; };
7CE58D4A1DD64A5B00128552 /* SVGPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE58D491DD64A5B00128552 /* SVGPoint.h */; };
7CE58D4E1DD694FE00128552 /* SVGRectTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE58D4D1DD694FE00128552 /* SVGRectTraits.h */; };
7CE58D501DD69A1E00128552 /* SVGNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE58D4F1DD69A1E00128552 /* SVGNumber.h */; };
@@ -11354,6 +11355,7 @@
7CD0BA031B8F79C9005CEBBE /* ActiveDOMCallbackMicrotask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveDOMCallbackMicrotask.h; sourceTree = "<group>"; };
7CD494CA1A86EB1D000A87EC /* RenderAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderAttachment.cpp; sourceTree = "<group>"; };
7CD494CB1A86EB1D000A87EC /* RenderAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderAttachment.h; sourceTree = "<group>"; };
+ 7CDE8EBC1F193BC500168FE7 /* CSSStyleDeclaration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSStyleDeclaration.cpp; sourceTree = "<group>"; };
7CE58D491DD64A5B00128552 /* SVGPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPoint.h; sourceTree = "<group>"; };
7CE58D4D1DD694FE00128552 /* SVGRectTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGRectTraits.h; sourceTree = "<group>"; };
7CE58D4F1DD69A1E00128552 /* SVGNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGNumber.h; sourceTree = "<group>"; };
@@ -25067,6 +25069,7 @@
E4C178960EE6903800824D69 /* CSSSelectorList.h */,
A80E6CCA0A1989CA007FB8C5 /* CSSShadowValue.cpp */,
A80E6CBE0A1989CA007FB8C5 /* CSSShadowValue.h */,
+ 7CDE8EBC1F193BC500168FE7 /* CSSStyleDeclaration.cpp */,
A80E6E0D0A19911C007FB8C5 /* CSSStyleDeclaration.h */,
142011AE0A003117008303F9 /* CSSStyleDeclaration.idl */,
A80E6CC50A1989CA007FB8C5 /* CSSStyleRule.cpp */,
@@ -30816,6 +30819,7 @@
49484FC4102CF23C00187DD3 /* CanvasPattern.cpp in Sources */,
49C7B9DC1042D32F0009D447 /* CanvasRenderingContext.cpp in Sources */,
49484FCA102CF23C00187DD3 /* CanvasRenderingContext2D.cpp in Sources */,
+ 7CDE8EBE1F193BCB00168FE7 /* CSSStyleDeclaration.cpp in Sources */,
49484FCD102CF23C00187DD3 /* CanvasStyle.cpp in Sources */,
072CA86116CB4DC3008AE131 /* CaptionUserPreferences.cpp in Sources */,
079D086C162F21F900DB8658 /* CaptionUserPreferencesMediaAF.cpp in Sources */,
Modified: trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp (219621 => 219622)
--- trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp 2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp 2017-07-18 20:12:15 UTC (rev 219622)
@@ -24,31 +24,16 @@
*/
#include "config.h"
-#include "JSCSSStyleDeclarationCustom.h"
+#include "JSCSSStyleDeclaration.h"
-#include "CSSPropertyNames.h"
-#include "CSSPropertyParser.h"
-#include "CSSRule.h"
-#include "CSSStyleDeclaration.h"
-#include "CSSStyleSheet.h"
-#include "CustomElementReactionQueue.h"
-#include "DeprecatedCSSOMPrimitiveValue.h"
-#include "HashTools.h"
-#include "JSCSSStyleDeclaration.h"
-#include "JSDOMConvertNullable.h"
+#include "DOMWrapperWorld.h"
+#include "JSCSSRuleCustom.h"
+#include "JSDOMConvertInterface.h"
#include "JSDOMConvertStrings.h"
#include "JSDeprecatedCSSOMValue.h"
-#include "JSNode.h"
+#include "JSNodeCustom.h"
#include "JSStyleSheetCustom.h"
-#include "RuntimeEnabledFeatures.h"
-#include "Settings.h"
-#include "StyleProperties.h"
#include "StyledElement.h"
-#include <runtime/IdentifierInlines.h>
-#include <runtime/StringPrototype.h>
-#include <wtf/ASCIICType.h>
-#include <wtf/text/AtomicString.h>
-#include <wtf/text/StringConcatenate.h>
using namespace JSC;
@@ -71,314 +56,6 @@
visitor.addOpaqueRoot(root(&wrapped()));
}
-enum class PropertyNamePrefix {
- None, Epub, CSS, Pixel, Pos, WebKit,
-#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
- Apple, KHTML,
-#endif
-};
-
-template<size_t prefixCStringLength>
-static inline bool matchesCSSPropertyNamePrefix(const StringImpl& propertyName, const char (&prefix)[prefixCStringLength])
-{
- size_t prefixLength = prefixCStringLength - 1;
-
- ASSERT(toASCIILower(propertyName[0]) == prefix[0]);
- const size_t offset = 1;
-
-#ifndef NDEBUG
- for (size_t i = 0; i < prefixLength; ++i)
- ASSERT(isASCIILower(prefix[i]));
- ASSERT(!prefix[prefixLength]);
- ASSERT(propertyName.length());
-#endif
-
- // The prefix within the property name must be followed by a capital letter.
- // Other characters in the prefix within the property name must be lowercase.
- if (propertyName.length() < prefixLength + 1)
- return false;
-
- for (size_t i = offset; i < prefixLength; ++i) {
- if (propertyName[i] != prefix[i])
- return false;
- }
-
- if (!isASCIIUpper(propertyName[prefixLength]))
- return false;
-
- return true;
-}
-
-static PropertyNamePrefix propertyNamePrefix(const StringImpl& propertyName)
-{
- ASSERT(propertyName.length());
-
- // First character of the prefix within the property name may be upper or lowercase.
- UChar firstChar = toASCIILower(propertyName[0]);
- switch (firstChar) {
-#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
- case 'a':
- if (RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled() && matchesCSSPropertyNamePrefix(propertyName, "apple"))
- return PropertyNamePrefix::Apple;
- break;
-#endif
- case 'c':
- if (matchesCSSPropertyNamePrefix(propertyName, "css"))
- return PropertyNamePrefix::CSS;
- break;
-#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
- case 'k':
- if (RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled() && matchesCSSPropertyNamePrefix(propertyName, "khtml"))
- return PropertyNamePrefix::KHTML;
- break;
-#endif
- case 'e':
- if (matchesCSSPropertyNamePrefix(propertyName, "epub"))
- return PropertyNamePrefix::Epub;
- break;
- case 'p':
- if (matchesCSSPropertyNamePrefix(propertyName, "pos"))
- return PropertyNamePrefix::Pos;
- if (matchesCSSPropertyNamePrefix(propertyName, "pixel"))
- return PropertyNamePrefix::Pixel;
- break;
- case 'w':
- if (matchesCSSPropertyNamePrefix(propertyName, "webkit"))
- return PropertyNamePrefix::WebKit;
- break;
- default:
- break;
- }
- return PropertyNamePrefix::None;
-}
-
-static inline void writeWebKitPrefix(char*& buffer)
-{
- *buffer++ = '-';
- *buffer++ = 'w';
- *buffer++ = 'e';
- *buffer++ = 'b';
- *buffer++ = 'k';
- *buffer++ = 'i';
- *buffer++ = 't';
- *buffer++ = '-';
-}
-
-static inline void writeEpubPrefix(char*& buffer)
-{
- *buffer++ = '-';
- *buffer++ = 'e';
- *buffer++ = 'p';
- *buffer++ = 'u';
- *buffer++ = 'b';
- *buffer++ = '-';
-}
-
-struct CSSPropertyInfo {
- CSSPropertyID propertyID;
- bool hadPixelOrPosPrefix;
-};
-
-static CSSPropertyInfo parseJavaScriptCSSPropertyName(PropertyName propertyName)
-{
- CSSPropertyInfo propertyInfo = {CSSPropertyInvalid, false};
- bool hadPixelOrPosPrefix = false;
-
- StringImpl* propertyNameString = propertyName.publicName();
- if (!propertyNameString)
- return propertyInfo;
- unsigned length = propertyNameString->length();
- if (!length)
- return propertyInfo;
-
- String stringForCache = String(propertyNameString);
- using CSSPropertyInfoMap = HashMap<String, CSSPropertyInfo>;
- static NeverDestroyed<CSSPropertyInfoMap> propertyInfoCache;
- propertyInfo = propertyInfoCache.get().get(stringForCache);
- if (propertyInfo.propertyID)
- return propertyInfo;
-
- const size_t bufferSize = maxCSSPropertyNameLength + 1;
- char buffer[bufferSize];
- char* bufferPtr = buffer;
- const char* name = bufferPtr;
-
- unsigned i = 0;
- // Prefixes CSS, Pixel, Pos are ignored.
- // Prefixes Apple, KHTML and Webkit are transposed to "-webkit-".
- // The prefix "Epub" becomes "-epub-".
- switch (propertyNamePrefix(*propertyNameString)) {
- case PropertyNamePrefix::None:
- if (isASCIIUpper((*propertyNameString)[0]))
- return propertyInfo;
- break;
- case PropertyNamePrefix::CSS:
- i += 3;
- break;
- case PropertyNamePrefix::Pixel:
- i += 5;
- hadPixelOrPosPrefix = true;
- break;
- case PropertyNamePrefix::Pos:
- i += 3;
- hadPixelOrPosPrefix = true;
- break;
-#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
- case PropertyNamePrefix::Apple:
- case PropertyNamePrefix::KHTML:
- ASSERT(RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled());
- writeWebKitPrefix(bufferPtr);
- i += 5;
- break;
-#endif
- case PropertyNamePrefix::Epub:
- writeEpubPrefix(bufferPtr);
- i += 4;
- break;
- case PropertyNamePrefix::WebKit:
- writeWebKitPrefix(bufferPtr);
- i += 6;
- break;
- }
-
- *bufferPtr++ = toASCIILower((*propertyNameString)[i++]);
-
- char* bufferEnd = buffer + bufferSize;
- char* stringEnd = bufferEnd - 1;
- size_t bufferSizeLeft = stringEnd - bufferPtr;
- size_t propertySizeLeft = length - i;
- if (propertySizeLeft > bufferSizeLeft)
- return propertyInfo;
-
- for (; i < length; ++i) {
- UChar c = (*propertyNameString)[i];
- if (!c || !isASCII(c))
- return propertyInfo; // illegal character
- if (isASCIIUpper(c)) {
- size_t bufferSizeLeft = stringEnd - bufferPtr;
- size_t propertySizeLeft = length - i + 1;
- if (propertySizeLeft > bufferSizeLeft)
- return propertyInfo;
- *bufferPtr++ = '-';
- *bufferPtr++ = toASCIILowerUnchecked(c);
- } else
- *bufferPtr++ = c;
- ASSERT_WITH_SECURITY_IMPLICATION(bufferPtr < bufferEnd);
- }
- ASSERT_WITH_SECURITY_IMPLICATION(bufferPtr < bufferEnd);
- *bufferPtr = '\0';
-
- unsigned outputLength = bufferPtr - buffer;
-#if PLATFORM(IOS)
- cssPropertyNameIOSAliasing(buffer, name, outputLength);
-#endif
-
- auto* hashTableEntry = findProperty(name, outputLength);
- if (auto propertyID = hashTableEntry ? hashTableEntry->id : 0) {
- propertyInfo.hadPixelOrPosPrefix = hadPixelOrPosPrefix;
- propertyInfo.propertyID = static_cast<CSSPropertyID>(propertyID);
- propertyInfoCache.get().add(stringForCache, propertyInfo);
- }
- return propertyInfo;
-}
-
-static inline JSValue stylePropertyGetter(ExecState& state, JSCSSStyleDeclaration& thisObject, CSSPropertyID propertyID, const RefPtr<CSSValue>& value)
-{
- if (value)
- return toJS<IDLNullable<IDLDOMString>>(state, value->cssText());
- // If the property is a shorthand property (such as "padding"), it can only be accessed using getPropertyValue.
- return toJS<IDLDOMString>(state, thisObject.wrapped().getPropertyValueInternal(propertyID));
-}
-
-static inline JSValue stylePropertyGetter(ExecState& state, JSCSSStyleDeclaration& thisObject, CSSPropertyID propertyID)
-{
- return stylePropertyGetter(state, thisObject, propertyID, thisObject.wrapped().getPropertyCSSValueInternal(propertyID));
-}
-
-static inline JSValue stylePropertyGetterPixelOrPosPrefix(ExecState& state, JSCSSStyleDeclaration& thisObject, CSSPropertyID propertyID)
-{
- // Call this version of the getter so that, e.g., pixelTop returns top as a number
- // in pixel units and posTop should does the same _if_ this is a positioned element.
- // FIXME: If not a positioned element, MSIE documentation says posTop should return 0; this rule is not implemented.
- auto value = thisObject.wrapped().getPropertyCSSValueInternal(propertyID);
- if (is<CSSPrimitiveValue>(value.get()))
- return jsNumber(downcast<CSSPrimitiveValue>(*value).floatValue(CSSPrimitiveValue::CSS_PX));
- return stylePropertyGetter(state, thisObject, propertyID, value);
-}
-
-static inline JSValue stylePropertyGetter(ExecState& state, JSCSSStyleDeclaration& thisObject, const CSSPropertyInfo& propertyInfo)
-{
- if (propertyInfo.hadPixelOrPosPrefix)
- return stylePropertyGetterPixelOrPosPrefix(state, thisObject, propertyInfo.propertyID);
- return stylePropertyGetter(state, thisObject, propertyInfo.propertyID);
-}
-
-// FIXME: This should be converted to be a named getter.
-bool JSCSSStyleDeclaration::getOwnPropertySlotDelegate(ExecState* state, PropertyName propertyName, PropertySlot& slot)
-{
- auto propertyInfo = parseJavaScriptCSSPropertyName(propertyName);
- if (!propertyInfo.propertyID)
- return false;
- slot.setValue(this, DontDelete, stylePropertyGetter(*state, *this, propertyInfo));
- return true;
-}
-
-// FIXME: This should be converted to be a named setter.
-static bool putCommon(JSCSSStyleDeclaration& thisObject, ExecState& state, PropertyName propertyName, JSValue value, bool& putResult)
-{
- CustomElementReactionStack customElementReactionStack;
- auto propertyInfo = parseJavaScriptCSSPropertyName(propertyName);
- if (!propertyInfo.propertyID)
- return false;
-
- auto propertyValue = convert<IDLTreatNullAsEmptyAdaptor<IDLDOMString>>(state, value);
- if (propertyInfo.hadPixelOrPosPrefix)
- propertyValue.append("px");
-
- bool important = false;
- if (Settings::shouldRespectPriorityInCSSAttributeSetters()) {
- auto importantIndex = propertyValue.findIgnoringASCIICase("!important");
- if (importantIndex && importantIndex != notFound) {
- important = true;
- propertyValue = propertyValue.left(importantIndex - 1);
- }
- }
-
- auto setPropertyInternalResult = thisObject.wrapped().setPropertyInternal(propertyInfo.propertyID, propertyValue, important);
- if (setPropertyInternalResult.hasException()) {
- auto& vm = state.vm();
- auto scope = DECLARE_THROW_SCOPE(vm);
- propagateException(state, scope, setPropertyInternalResult.releaseException());
- return true;
- }
- putResult = setPropertyInternalResult.releaseReturnValue();
- return true;
-}
-
-bool JSCSSStyleDeclaration::put(JSCell* cell, ExecState* state, PropertyName propertyName, JSValue value, PutPropertySlot& putPropertySlot)
-{
- auto* thisObject = jsCast<JSCSSStyleDeclaration*>(cell);
- ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-
- bool putResult = false;
- if (putCommon(*thisObject, *state, propertyName, value, putResult))
- return putResult;
-
- return JSObject::put(thisObject, state, propertyName, value, putPropertySlot);
-}
-
-bool JSCSSStyleDeclaration::putByIndex(JSCell* cell, ExecState* state, unsigned index, JSValue value, bool shouldThrow)
-{
- auto* thisObject = jsCast<JSCSSStyleDeclaration*>(cell);
- ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-
- bool putResult = false;
- if (putCommon(*thisObject, *state, Identifier::from(state, index), value, putResult))
- return putResult;
-
- return JSObject::putByIndex(cell, state, index, value, shouldThrow);
-}
-
JSValue JSCSSStyleDeclaration::getPropertyCSSValue(ExecState& state)
{
VM& vm = state.vm();
@@ -387,8 +64,8 @@
if (UNLIKELY(state.argumentCount() < 1))
return throwException(&state, scope, createNotEnoughArgumentsError(&state));
- auto propertyName = state.uncheckedArgument(0).toWTFString(&state);
- RETURN_IF_EXCEPTION(scope, JSValue());
+ auto propertyName = convert<IDLDOMString>(state, state.uncheckedArgument(0));
+ RETURN_IF_EXCEPTION(scope, { });
auto value = wrapped().getPropertyCSSValue(propertyName);
if (!value)
@@ -395,29 +72,7 @@
return jsNull();
globalObject()->world().m_deprecatedCSSOMValueRoots.add(value.get(), root(&wrapped())); // Balanced by JSDeprecatedCSSOMValueOwner::finalize().
- return toJS(&state, globalObject(), *value);
+ return toJS<IDLInterface<DeprecatedCSSOMValue>>(state, *globalObject(), *value);
}
-void JSCSSStyleDeclaration::getOwnPropertyNames(JSObject* object, ExecState* state, PropertyNameArray& propertyNames, EnumerationMode mode)
-{
- static const Identifier* const cssPropertyNames = [state] {
- String names[numCSSProperties];
- for (int i = 0; i < numCSSProperties; ++i)
- names[i] = getJSPropertyName(static_cast<CSSPropertyID>(firstCSSProperty + i));
- std::sort(&names[0], &names[numCSSProperties], WTF::codePointCompareLessThan);
- auto* identifiers = new Identifier[numCSSProperties];
- for (int i = 0; i < numCSSProperties; ++i)
- identifiers[i] = Identifier::fromString(state, names[i]);
- return identifiers;
- }();
-
- unsigned length = jsCast<JSCSSStyleDeclaration*>(object)->wrapped().length();
- for (unsigned i = 0; i < length; ++i)
- propertyNames.add(Identifier::from(state, i));
- for (int i = 0; i < numCSSProperties; ++i)
- propertyNames.add(cssPropertyNames[i]);
-
- Base::getOwnPropertyNames(object, state, propertyNames, mode);
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (219621 => 219622)
--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2017-07-18 20:12:15 UTC (rev 219622)
@@ -667,7 +667,7 @@
# 1.3. Set ignoreNamedProps to true.
# NOTE: Setting ignoreNamedProps has the effect of skipping step 2, so we can early return here
# rather than going through the paces of having an actual ignoreNamedProps update.
- if ($namedGetterOperation || $interface->extendedAttributes->{CustomGetOwnPropertySlotAndDescriptor} || $interface->extendedAttributes->{Plugin}) {
+ if ($namedGetterOperation || $interface->extendedAttributes->{Plugin}) {
push(@$outputArray, " return JSObject::getOwnPropertySlot(object, state, propertyName, slot);\n");
}
push(@$outputArray, " }\n");
@@ -702,12 +702,6 @@
push(@$outputArray, " }\n");
}
- # FIXME: There is only one remaining user of this, CSSStyleDeclaration.idl. Let's get them onto named / indexed getters.
- if ($interface->extendedAttributes->{CustomGetOwnPropertySlotAndDescriptor}) {
- push(@$outputArray, " if (thisObject->getOwnPropertySlotDelegate(state, propertyName, slot))\n");
- push(@$outputArray, " return true;\n");
- }
-
if ($interface->extendedAttributes->{Plugin}) {
AddToImplIncludes("JSPluginElementFunctions.h");
push(@$outputArray, " if (pluginElementCustomGetOwnPropertySlot(thisObject, state, propertyName, slot))\n");
@@ -779,7 +773,7 @@
# 1.3. Set ignoreNamedProps to true.
# NOTE: Setting ignoreNamedProps has the effect of skipping step 2, so we can early return here
# rather than going through the paces of having an actual ignoreNamedProps update.
- if ($namedGetterOperation || $interface->extendedAttributes->{CustomGetOwnPropertySlotAndDescriptor} || $interface->extendedAttributes->{Plugin}) {
+ if ($namedGetterOperation || $interface->extendedAttributes->{Plugin}) {
push(@$outputArray, " return JSObject::getOwnPropertySlotByIndex(object, state, index, slot);\n");
}
push(@$outputArray, " }\n");
@@ -816,14 +810,6 @@
push(@$outputArray, " }\n");
}
- # FIXME: There is only one remaining user of this, CSSStyleDeclaration.idl. Let's get them onto named / indexed getters.
- if ($interface->extendedAttributes->{CustomGetOwnPropertySlotAndDescriptor}) {
- &$propertyNameGeneration();
-
- push(@$outputArray, " if (thisObject->getOwnPropertySlotDelegate(state, propertyName, slot))\n");
- push(@$outputArray, " return true;\n");
- }
-
if ($interface->extendedAttributes->{Plugin}) {
&$propertyNameGeneration();
@@ -916,12 +902,20 @@
push(@$outputArray, $indent . "auto throwScope = DECLARE_THROW_SCOPE(state->vm());\n");
push(@$outputArray, $indent . "auto nativeValue = ${nativeValue};\n");
push(@$outputArray, $indent . "RETURN_IF_EXCEPTION(throwScope, true);\n");
-
+
+ push(@$outputArray, $indent . "bool isPropertySupported = true;\n") if $namedSetterOperation->extendedAttributes->{CallNamedSetterOnlyForSupportedProperties};
+
my $namedSetterFunctionName = $namedSetterOperation->name || "setNamedItem";
my $nativeValuePassExpression = PassArgumentExpression("nativeValue", $argument);
- my $functionString = "thisObject->wrapped().${namedSetterFunctionName}(propertyNameToString(propertyName), ${nativeValuePassExpression})";
+
+ my @arguments = ();
+ push(@arguments, "propertyNameToString(propertyName)");
+ push(@arguments, $nativeValuePassExpression);
+ push(@arguments, "isPropertySupported") if $namedSetterOperation->extendedAttributes->{CallNamedSetterOnlyForSupportedProperties};
+
+ my $functionString = "thisObject->wrapped().${namedSetterFunctionName}(" . join(", ", @arguments) . ")";
$functionString = "propagateException(*state, throwScope, ${functionString})" if NeedsExplicitPropagateExceptionCall($namedSetterOperation);
-
+
push(@$outputArray, $indent . $functionString . ";\n");
}
@@ -966,10 +960,14 @@
push(@$outputArray, " if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {\n");
$additionalIndent .= " ";
}
-
+
GenerateInvokeNamedPropertySetter($outputArray, $additionalIndent . " ", $interface, $namedSetterOperation, "value");
+ if ($namedSetterOperation->extendedAttributes->{CallNamedSetterOnlyForSupportedProperties}) {
+ push(@$outputArray, $additionalIndent . " if (!isPropertySupported)\n");
+ push(@$outputArray, $additionalIndent . " return JSObject::put(thisObject, state, propertyName, value, putPropertySlot);\n");
+ }
push(@$outputArray, $additionalIndent . " return true;\n");
-
+
if (!$overrideBuiltins) {
push(@$outputArray, " }\n");
}
@@ -1000,7 +998,7 @@
my $indexedSetterOperation = GetIndexedSetterOperation($interface);
my $overrideBuiltins = $codeGenerator->InheritsExtendedAttribute($interface, "OverrideBuiltins");
- my $ellidesCallsToBase = ($namedSetterOperation && $overrideBuiltins) && !$interface->extendedAttributes->{Plugin};
+ my $ellidesCallsToBase = ($namedSetterOperation && $overrideBuiltins) && !$interface->extendedAttributes->{Plugin} && !$namedSetterOperation->extendedAttributes->{CallNamedSetterOnlyForSupportedProperties};
push(@$outputArray, "bool ${className}::putByIndex(JSCell* cell, ExecState* state, unsigned index, JSValue value, bool" . (!$ellidesCallsToBase ? " shouldThrow" : "") . ")\n");
push(@$outputArray, "{\n");
@@ -1033,6 +1031,10 @@
}
GenerateInvokeNamedPropertySetter($outputArray, $additionalIndent . " ", $interface, $namedSetterOperation, "value");
+ if ($namedSetterOperation->extendedAttributes->{CallNamedSetterOnlyForSupportedProperties}) {
+ push(@$outputArray, $additionalIndent . " if (!isPropertySupported)\n");
+ push(@$outputArray, $additionalIndent . " return JSObject::putByIndex(cell, state, index, value, shouldThrow);\n");
+ }
push(@$outputArray, $additionalIndent . " return true;\n");
if (!$overrideBuiltins) {
@@ -1106,15 +1108,16 @@
# 1. If O supports indexed properties and P is an array index property name, then:
if (GetIndexedGetterOperation($interface)) {
- push(@$outputArray, " if (auto index = parseIndex(propertyName)) {\n");
-
# NOTE: The numbers are out of order because there is no reason doing steps 1, 3, and 4 if there
# is no indexed property setter.
-
+
if (!$indexedSetterOperation) {
# 2. If O does not implement an interface with an indexed property setter, then return false.
- push(@$outputArray, " return false;\n");
+ push(@$outputArray, " if (parseIndex(propertyName))\n");
+ push(@$outputArray, " return false;\n\n");
} else {
+ push(@$outputArray, " if (auto index = parseIndex(propertyName)) {\n");
+
# 1. If the result of calling IsDataDescriptor(Desc) is false, then return false.
push(@$outputArray, " if (!propertyDescriptor.isDataDescriptor())\n");
push(@$outputArray, " return false;\n");
@@ -1124,8 +1127,8 @@
# 4. Return true.
push(@$outputArray, " return true;\n");
+ push(@$outputArray, " }\n\n");
}
- push(@$outputArray, " }\n\n");
}
# 2. If O supports named properties, O does not implement an interface with the [Global] or [PrimaryGlobal]
@@ -1169,7 +1172,10 @@
# 2.2.2. Invoke the named property setter with P and Desc.[[Value]].
GenerateInvokeNamedPropertySetter($outputArray, $additionalIndent . " ", $interface, $namedSetterOperation, "propertyDescriptor.value()");
-
+ if ($namedSetterOperation->extendedAttributes->{CallNamedSetterOnlyForSupportedProperties}) {
+ push(@$outputArray, $additionalIndent . " if (!isPropertySupported)\n");
+ push(@$outputArray, $additionalIndent . " return JSObject::defineOwnProperty(object, state, propertyName, propertyDescriptor, shouldThrow);\n");
+ }
# 2.2.3. Return true.
push(@$outputArray, $additionalIndent . " return true;\n");
}
@@ -1810,7 +1816,6 @@
{
my $interface = shift;
return $interface->extendedAttributes->{CustomGetOwnPropertySlot}
- || $interface->extendedAttributes->{CustomGetOwnPropertySlotAndDescriptor}
|| $interface->extendedAttributes->{Plugin}
|| GetIndexedGetterOperation($interface)
|| GetNamedGetterOperation($interface);
@@ -1836,6 +1841,9 @@
sub InstanceOverridesDefineOwnProperty
{
my $interface = shift;
+
+ return 0 if $interface->extendedAttributes->{DefaultDefineOwnProperty};
+
return $interface->extendedAttributes->{CustomDefineOwnProperty}
|| GetIndexedSetterOperation($interface)
|| GetNamedSetterOperation($interface);
@@ -2530,7 +2538,7 @@
my $namedGetterOperation = GetNamedGetterOperation($interface);
my $indexedGetterOperation = GetIndexedGetterOperation($interface);
- # FIXME: Why doesn't this also include Indexed Getters, [CustomGetOwnPropertySlot] and [CustomGetOwnPropertySlotAndDescriptor]
+ # FIXME: Why doesn't this also include Indexed Getters and [CustomGetOwnPropertySlot]
if ($namedGetterOperation) {
if ($codeGenerator->InheritsExtendedAttribute($interface, "OverrideBuiltins")) {
$structureFlags{"JSC::GetOwnPropertySlotIsImpure"} = 1;
@@ -2793,10 +2801,6 @@
push(@headerContent, " void finishCreation(JSC::VM&);\n");
}
- if ($interface->extendedAttributes->{CustomGetOwnPropertySlotAndDescriptor}) {
- push(@headerContent, " bool getOwnPropertySlotDelegate(JSC::ExecState*, JSC::PropertyName, JSC::PropertySlot&);\n");
- }
-
push(@headerContent, "};\n\n");
if (ShouldGenerateWrapperOwnerCode($hasParent, $interface)) {
Modified: trunk/Source/WebCore/bindings/scripts/IDLAttributes.json (219621 => 219622)
--- trunk/Source/WebCore/bindings/scripts/IDLAttributes.json 2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/bindings/scripts/IDLAttributes.json 2017-07-18 20:12:15 UTC (rev 219622)
@@ -34,6 +34,9 @@
"CallbackNeedsOperatorEqual": {
"contextsAllowed": ["callback-function"]
},
+ "CallNamedSetterOnlyForSupportedProperties": {
+ "contextsAllowed": ["operation"]
+ },
"CallWith": {
"contextsAllowed": ["attribute", "operation"],
"values": ["Document", "ScriptExecutionContext", "ScriptState", "GlobalObject", "ActiveWindow", "FirstWindow", "ResponsibleDocument", "World"]
@@ -99,9 +102,6 @@
"CustomGetOwnPropertySlot": {
"contextsAllowed": ["interface"]
},
- "CustomGetOwnPropertySlotAndDescriptor": {
- "contextsAllowed": ["interface"]
- },
"CustomGetPrototype": {
"contextsAllowed": ["interface"]
},
@@ -142,6 +142,9 @@
"contextsAllowed": ["interface", "attribute", "operation"],
"values": ["", "ReadDOM", "Getter"]
},
+ "DefaultDefineOwnProperty": {
+ "contextsAllowed": ["interface"]
+ },
"DoNotCheckConstants": {
"contextsAllowed": ["interface"]
},
Added: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp (0 => 219622)
--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp 2017-07-18 20:12:15 UTC (rev 219622)
@@ -0,0 +1,401 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "JSTestNamedSetterWithIndexedGetter.h"
+
+#include "JSDOMAbstractOperations.h"
+#include "JSDOMBinding.h"
+#include "JSDOMConstructorNotConstructable.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMExceptionHandling.h"
+#include "JSDOMOperation.h"
+#include "JSDOMWrapperCache.h"
+#include "URL.h"
+#include <runtime/FunctionPrototype.h>
+#include <runtime/JSCInlines.h>
+#include <runtime/PropertyNameArray.h>
+#include <wtf/GetPtr.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+// Functions
+
+JSC::EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterPrototypeFunctionNamedSetter(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterPrototypeFunctionIndexedSetter(JSC::ExecState*);
+
+// Attributes
+
+JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+bool setJSTestNamedSetterWithIndexedGetterConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
+
+class JSTestNamedSetterWithIndexedGetterPrototype : public JSC::JSNonFinalObject {
+public:
+ using Base = JSC::JSNonFinalObject;
+ static JSTestNamedSetterWithIndexedGetterPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
+ {
+ JSTestNamedSetterWithIndexedGetterPrototype* ptr = new (NotNull, JSC::allocateCell<JSTestNamedSetterWithIndexedGetterPrototype>(vm.heap)) JSTestNamedSetterWithIndexedGetterPrototype(vm, globalObject, structure);
+ ptr->finishCreation(vm);
+ return ptr;
+ }
+
+ DECLARE_INFO;
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
+private:
+ JSTestNamedSetterWithIndexedGetterPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
+ : JSC::JSNonFinalObject(vm, structure)
+ {
+ }
+
+ void finishCreation(JSC::VM&);
+};
+
+using JSTestNamedSetterWithIndexedGetterConstructor = JSDOMConstructorNotConstructable<JSTestNamedSetterWithIndexedGetter>;
+
+template<> JSValue JSTestNamedSetterWithIndexedGetterConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
+{
+ UNUSED_PARAM(vm);
+ return globalObject.functionPrototype();
+}
+
+template<> void JSTestNamedSetterWithIndexedGetterConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ putDirect(vm, vm.propertyNames->prototype, JSTestNamedSetterWithIndexedGetter::prototype(vm, globalObject), DontDelete | ReadOnly | DontEnum);
+ putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("TestNamedSetterWithIndexedGetter"))), ReadOnly | DontEnum);
+ putDirect(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum);
+}
+
+template<> const ClassInfo JSTestNamedSetterWithIndexedGetterConstructor::s_info = { "TestNamedSetterWithIndexedGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestNamedSetterWithIndexedGetterConstructor) };
+
+/* Hash table for prototype */
+
+static const HashTableValue JSTestNamedSetterWithIndexedGetterPrototypeTableValues[] =
+{
+ { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestNamedSetterWithIndexedGetterConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestNamedSetterWithIndexedGetterConstructor) } },
+ { "namedSetter", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNamedSetterWithIndexedGetterPrototypeFunctionNamedSetter), (intptr_t) (2) } },
+ { "indexedSetter", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNamedSetterWithIndexedGetterPrototypeFunctionIndexedSetter), (intptr_t) (1) } },
+};
+
+const ClassInfo JSTestNamedSetterWithIndexedGetterPrototype::s_info = { "TestNamedSetterWithIndexedGetterPrototype", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestNamedSetterWithIndexedGetterPrototype) };
+
+void JSTestNamedSetterWithIndexedGetterPrototype::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ reifyStaticProperties(vm, JSTestNamedSetterWithIndexedGetterPrototypeTableValues, *this);
+}
+
+const ClassInfo JSTestNamedSetterWithIndexedGetter::s_info = { "TestNamedSetterWithIndexedGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestNamedSetterWithIndexedGetter) };
+
+JSTestNamedSetterWithIndexedGetter::JSTestNamedSetterWithIndexedGetter(Structure* structure, JSDOMGlobalObject& globalObject, Ref<TestNamedSetterWithIndexedGetter>&& impl)
+ : JSDOMWrapper<TestNamedSetterWithIndexedGetter>(structure, globalObject, WTFMove(impl))
+{
+}
+
+void JSTestNamedSetterWithIndexedGetter::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(vm, info()));
+
+}
+
+JSObject* JSTestNamedSetterWithIndexedGetter::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ return JSTestNamedSetterWithIndexedGetterPrototype::create(vm, &globalObject, JSTestNamedSetterWithIndexedGetterPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
+}
+
+JSObject* JSTestNamedSetterWithIndexedGetter::prototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ return getDOMPrototype<JSTestNamedSetterWithIndexedGetter>(vm, globalObject);
+}
+
+JSValue JSTestNamedSetterWithIndexedGetter::getConstructor(VM& vm, const JSGlobalObject* globalObject)
+{
+ return getDOMConstructor<JSTestNamedSetterWithIndexedGetterConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
+}
+
+void JSTestNamedSetterWithIndexedGetter::destroy(JSC::JSCell* cell)
+{
+ JSTestNamedSetterWithIndexedGetter* thisObject = static_cast<JSTestNamedSetterWithIndexedGetter*>(cell);
+ thisObject->JSTestNamedSetterWithIndexedGetter::~JSTestNamedSetterWithIndexedGetter();
+}
+
+bool JSTestNamedSetterWithIndexedGetter::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot& slot)
+{
+ auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetter*>(object);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ if (auto index = parseIndex(propertyName)) {
+ if (index.value() < thisObject->wrapped().length()) {
+ auto value = toJS<IDLDOMString>(*state, thisObject->wrapped().indexedSetter(index.value()));
+ slot.setValue(thisObject, ReadOnly, value);
+ return true;
+ }
+ return JSObject::getOwnPropertySlot(object, state, propertyName, slot);
+ }
+ using GetterIDLType = IDLDOMString;
+ auto getterFunctor = [] (auto& thisObject, auto propertyName) -> std::optional<typename GetterIDLType::ImplementationType> {
+ auto result = thisObject.wrapped().namedItem(propertyNameToAtomicString(propertyName));
+ if (!GetterIDLType::isNullValue(result))
+ return typename GetterIDLType::ImplementationType { GetterIDLType::extractValueFromNullable(result) };
+ return std::nullopt;
+ };
+ if (auto namedProperty = accessVisibleNamedProperty<OverrideBuiltins::No>(*state, *thisObject, propertyName, getterFunctor)) {
+ auto value = toJS<IDLDOMString>(*state, WTFMove(namedProperty.value()));
+ slot.setValue(thisObject, 0, value);
+ return true;
+ }
+ return JSObject::getOwnPropertySlot(object, state, propertyName, slot);
+}
+
+bool JSTestNamedSetterWithIndexedGetter::getOwnPropertySlotByIndex(JSObject* object, ExecState* state, unsigned index, PropertySlot& slot)
+{
+ auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetter*>(object);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ if (LIKELY(index <= MAX_ARRAY_INDEX)) {
+ if (index < thisObject->wrapped().length()) {
+ auto value = toJS<IDLDOMString>(*state, thisObject->wrapped().indexedSetter(index));
+ slot.setValue(thisObject, ReadOnly, value);
+ return true;
+ }
+ return JSObject::getOwnPropertySlotByIndex(object, state, index, slot);
+ }
+ auto propertyName = Identifier::from(state, index);
+ using GetterIDLType = IDLDOMString;
+ auto getterFunctor = [] (auto& thisObject, auto propertyName) -> std::optional<typename GetterIDLType::ImplementationType> {
+ auto result = thisObject.wrapped().namedItem(propertyNameToAtomicString(propertyName));
+ if (!GetterIDLType::isNullValue(result))
+ return typename GetterIDLType::ImplementationType { GetterIDLType::extractValueFromNullable(result) };
+ return std::nullopt;
+ };
+ if (auto namedProperty = accessVisibleNamedProperty<OverrideBuiltins::No>(*state, *thisObject, propertyName, getterFunctor)) {
+ auto value = toJS<IDLDOMString>(*state, WTFMove(namedProperty.value()));
+ slot.setValue(thisObject, 0, value);
+ return true;
+ }
+ return JSObject::getOwnPropertySlotByIndex(object, state, index, slot);
+}
+
+void JSTestNamedSetterWithIndexedGetter::getOwnPropertyNames(JSObject* object, ExecState* state, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+ auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetter*>(object);
+ ASSERT_GC_OBJECT_INHERITS(object, info());
+ for (unsigned i = 0, count = thisObject->wrapped().length(); i < count; ++i)
+ propertyNames.add(Identifier::from(state, i));
+ for (auto& propertyName : thisObject->wrapped().supportedPropertyNames())
+ propertyNames.add(Identifier::fromString(state, propertyName));
+ JSObject::getOwnPropertyNames(object, state, propertyNames, mode);
+}
+
+bool JSTestNamedSetterWithIndexedGetter::put(JSCell* cell, ExecState* state, PropertyName propertyName, JSValue value, PutPropertySlot& putPropertySlot)
+{
+ auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetter*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+
+ if (!propertyName.isSymbol()) {
+ PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
+ JSValue prototype = thisObject->getPrototypeDirect();
+ if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
+ auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+ auto nativeValue = convert<IDLDOMString>(*state, value);
+ RETURN_IF_EXCEPTION(throwScope, true);
+ thisObject->wrapped().namedSetter(propertyNameToString(propertyName), WTFMove(nativeValue));
+ return true;
+ }
+ }
+
+ return JSObject::put(thisObject, state, propertyName, value, putPropertySlot);
+}
+
+bool JSTestNamedSetterWithIndexedGetter::putByIndex(JSCell* cell, ExecState* state, unsigned index, JSValue value, bool shouldThrow)
+{
+ auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetter*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+
+ auto propertyName = Identifier::from(state, index);
+ PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
+ JSValue prototype = thisObject->getPrototypeDirect();
+ if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
+ auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+ auto nativeValue = convert<IDLDOMString>(*state, value);
+ RETURN_IF_EXCEPTION(throwScope, true);
+ thisObject->wrapped().namedSetter(propertyNameToString(propertyName), WTFMove(nativeValue));
+ return true;
+ }
+
+ return JSObject::putByIndex(cell, state, index, value, shouldThrow);
+}
+
+bool JSTestNamedSetterWithIndexedGetter::defineOwnProperty(JSObject* object, ExecState* state, PropertyName propertyName, const PropertyDescriptor& propertyDescriptor, bool shouldThrow)
+{
+ auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetter*>(object);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+
+ if (parseIndex(propertyName))
+ return false;
+
+ if (!propertyName.isSymbol()) {
+ PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
+ if (!JSObject::getOwnPropertySlot(thisObject, state, propertyName, slot)) {
+ if (!propertyDescriptor.isDataDescriptor())
+ return false;
+ auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+ auto nativeValue = convert<IDLDOMString>(*state, propertyDescriptor.value());
+ RETURN_IF_EXCEPTION(throwScope, true);
+ thisObject->wrapped().namedSetter(propertyNameToString(propertyName), WTFMove(nativeValue));
+ return true;
+ }
+ }
+
+ PropertyDescriptor newPropertyDescriptor = propertyDescriptor;
+ newPropertyDescriptor.setConfigurable(true);
+ return JSObject::defineOwnProperty(object, state, propertyName, newPropertyDescriptor, shouldThrow);
+}
+
+template<> inline JSTestNamedSetterWithIndexedGetter* IDLOperation<JSTestNamedSetterWithIndexedGetter>::cast(ExecState& state)
+{
+ return jsDynamicDowncast<JSTestNamedSetterWithIndexedGetter*>(state.vm(), state.thisValue());
+}
+
+EncodedJSValue jsTestNamedSetterWithIndexedGetterConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+ VM& vm = state->vm();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ auto* prototype = jsDynamicDowncast<JSTestNamedSetterWithIndexedGetterPrototype*>(vm, JSValue::decode(thisValue));
+ if (UNLIKELY(!prototype))
+ return throwVMTypeError(state, throwScope);
+ return JSValue::encode(JSTestNamedSetterWithIndexedGetter::getConstructor(state->vm(), prototype->globalObject()));
+}
+
+bool setJSTestNamedSetterWithIndexedGetterConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
+{
+ VM& vm = state->vm();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ auto* prototype = jsDynamicDowncast<JSTestNamedSetterWithIndexedGetterPrototype*>(vm, JSValue::decode(thisValue));
+ if (UNLIKELY(!prototype)) {
+ throwVMTypeError(state, throwScope);
+ return false;
+ }
+ // Shadowing a built-in constructor
+ return prototype->putDirect(state->vm(), state->propertyNames().constructor, JSValue::decode(encodedValue));
+}
+
+static inline JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterPrototypeFunctionNamedSetterBody(JSC::ExecState* state, typename IDLOperation<JSTestNamedSetterWithIndexedGetter>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+ UNUSED_PARAM(state);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(state->argumentCount() < 2))
+ return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+ auto name = convert<IDLDOMString>(*state, state->uncheckedArgument(0));
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ auto value = convert<IDLDOMString>(*state, state->uncheckedArgument(1));
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ impl.namedSetter(WTFMove(name), WTFMove(value));
+ return JSValue::encode(jsUndefined());
+}
+
+EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterPrototypeFunctionNamedSetter(ExecState* state)
+{
+ return IDLOperation<JSTestNamedSetterWithIndexedGetter>::call<jsTestNamedSetterWithIndexedGetterPrototypeFunctionNamedSetterBody>(*state, "namedSetter");
+}
+
+static inline JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterPrototypeFunctionIndexedSetterBody(JSC::ExecState* state, typename IDLOperation<JSTestNamedSetterWithIndexedGetter>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+ UNUSED_PARAM(state);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(state->argumentCount() < 1))
+ return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+ auto index = convert<IDLUnsignedLong>(*state, state->uncheckedArgument(0));
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ return JSValue::encode(toJS<IDLDOMString>(*state, impl.indexedSetter(WTFMove(index))));
+}
+
+EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterPrototypeFunctionIndexedSetter(ExecState* state)
+{
+ return IDLOperation<JSTestNamedSetterWithIndexedGetter>::call<jsTestNamedSetterWithIndexedGetterPrototypeFunctionIndexedSetterBody>(*state, "indexedSetter");
+}
+
+bool JSTestNamedSetterWithIndexedGetterOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
+{
+ UNUSED_PARAM(handle);
+ UNUSED_PARAM(visitor);
+ return false;
+}
+
+void JSTestNamedSetterWithIndexedGetterOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
+{
+ auto* jsTestNamedSetterWithIndexedGetter = static_cast<JSTestNamedSetterWithIndexedGetter*>(handle.slot()->asCell());
+ auto& world = *static_cast<DOMWrapperWorld*>(context);
+ uncacheWrapper(world, &jsTestNamedSetterWithIndexedGetter->wrapped(), jsTestNamedSetterWithIndexedGetter);
+}
+
+#if ENABLE(BINDING_INTEGRITY)
+#if PLATFORM(WIN)
+#pragma warning(disable: 4483)
+extern "C" { extern void (*const __identifier("??_7TestNamedSetterWithIndexedGetter@WebCore@@6B@")[])(); }
+#else
+extern "C" { extern void* _ZTVN7WebCore32TestNamedSetterWithIndexedGetterE[]; }
+#endif
+#endif
+
+JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<TestNamedSetterWithIndexedGetter>&& impl)
+{
+
+#if ENABLE(BINDING_INTEGRITY)
+ void* actualVTablePointer = *(reinterpret_cast<void**>(impl.ptr()));
+#if PLATFORM(WIN)
+ void* expectedVTablePointer = reinterpret_cast<void*>(__identifier("??_7TestNamedSetterWithIndexedGetter@WebCore@@6B@"));
+#else
+ void* expectedVTablePointer = &_ZTVN7WebCore32TestNamedSetterWithIndexedGetterE[2];
+#endif
+
+ // If this fails TestNamedSetterWithIndexedGetter does not have a vtable, so you need to add the
+ // ImplementationLacksVTable attribute to the interface definition
+ static_assert(std::is_polymorphic<TestNamedSetterWithIndexedGetter>::value, "TestNamedSetterWithIndexedGetter is not polymorphic");
+
+ // If you hit this assertion you either have a use after free bug, or
+ // TestNamedSetterWithIndexedGetter has subclasses. If TestNamedSetterWithIndexedGetter has subclasses that get passed
+ // to toJS() we currently require TestNamedSetterWithIndexedGetter you to opt out of binding hardening
+ // by adding the SkipVTableValidation attribute to the interface IDL definition
+ RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
+#endif
+ return createWrapper<TestNamedSetterWithIndexedGetter>(globalObject, WTFMove(impl));
+}
+
+JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, TestNamedSetterWithIndexedGetter& impl)
+{
+ return wrap(state, globalObject, impl);
+}
+
+TestNamedSetterWithIndexedGetter* JSTestNamedSetterWithIndexedGetter::toWrapped(JSC::VM& vm, JSC::JSValue value)
+{
+ if (auto* wrapper = jsDynamicDowncast<JSTestNamedSetterWithIndexedGetter*>(vm, value))
+ return &wrapper->wrapped();
+ return nullptr;
+}
+
+}
Added: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.h (0 => 219622)
--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.h (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.h 2017-07-18 20:12:15 UTC (rev 219622)
@@ -0,0 +1,93 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#include "JSDOMWrapper.h"
+#include "TestNamedSetterWithIndexedGetter.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+class JSTestNamedSetterWithIndexedGetter : public JSDOMWrapper<TestNamedSetterWithIndexedGetter> {
+public:
+ using Base = JSDOMWrapper<TestNamedSetterWithIndexedGetter>;
+ static JSTestNamedSetterWithIndexedGetter* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<TestNamedSetterWithIndexedGetter>&& impl)
+ {
+ JSTestNamedSetterWithIndexedGetter* ptr = new (NotNull, JSC::allocateCell<JSTestNamedSetterWithIndexedGetter>(globalObject->vm().heap)) JSTestNamedSetterWithIndexedGetter(structure, *globalObject, WTFMove(impl));
+ ptr->finishCreation(globalObject->vm());
+ return ptr;
+ }
+
+ static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
+ static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
+ static TestNamedSetterWithIndexedGetter* toWrapped(JSC::VM&, JSC::JSValue);
+ static bool getOwnPropertySlot(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName, JSC::PropertySlot&);
+ static bool getOwnPropertySlotByIndex(JSC::JSObject*, JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
+ static void getOwnPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode = JSC::EnumerationMode());
+ static bool put(JSC::JSCell*, JSC::ExecState*, JSC::PropertyName, JSC::JSValue, JSC::PutPropertySlot&);
+ static bool putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue, bool shouldThrow);
+ static bool defineOwnProperty(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName, const JSC::PropertyDescriptor&, bool shouldThrow);
+ static void destroy(JSC::JSCell*);
+
+ DECLARE_INFO;
+
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
+ static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
+public:
+ static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
+protected:
+ JSTestNamedSetterWithIndexedGetter(JSC::Structure*, JSDOMGlobalObject&, Ref<TestNamedSetterWithIndexedGetter>&&);
+
+ void finishCreation(JSC::VM&);
+};
+
+class JSTestNamedSetterWithIndexedGetterOwner : public JSC::WeakHandleOwner {
+public:
+ virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
+ virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
+};
+
+inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, TestNamedSetterWithIndexedGetter*)
+{
+ static NeverDestroyed<JSTestNamedSetterWithIndexedGetterOwner> owner;
+ return &owner.get();
+}
+
+inline void* wrapperKey(TestNamedSetterWithIndexedGetter* wrappableObject)
+{
+ return wrappableObject;
+}
+
+JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, TestNamedSetterWithIndexedGetter&);
+inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, TestNamedSetterWithIndexedGetter* impl) { return impl ? toJS(state, globalObject, *impl) : JSC::jsNull(); }
+JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject*, Ref<TestNamedSetterWithIndexedGetter>&&);
+inline JSC::JSValue toJSNewlyCreated(JSC::ExecState* state, JSDOMGlobalObject* globalObject, RefPtr<TestNamedSetterWithIndexedGetter>&& impl) { return impl ? toJSNewlyCreated(state, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
+
+template<> struct JSDOMWrapperConverterTraits<TestNamedSetterWithIndexedGetter> {
+ using WrapperClass = JSTestNamedSetterWithIndexedGetter;
+ using ToWrappedReturnType = TestNamedSetterWithIndexedGetter*;
+};
+
+} // namespace WebCore
Added: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp (0 => 219622)
--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp 2017-07-18 20:12:15 UTC (rev 219622)
@@ -0,0 +1,451 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "JSTestNamedSetterWithIndexedGetterAndSetter.h"
+
+#include "JSDOMAbstractOperations.h"
+#include "JSDOMBinding.h"
+#include "JSDOMConstructorNotConstructable.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMExceptionHandling.h"
+#include "JSDOMOperation.h"
+#include "JSDOMWrapperCache.h"
+#include "URL.h"
+#include <runtime/FunctionPrototype.h>
+#include <runtime/JSCInlines.h>
+#include <runtime/PropertyNameArray.h>
+#include <wtf/GetPtr.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+// Functions
+
+JSC::EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionNamedSetter(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetter(JSC::ExecState*);
+
+// Attributes
+
+JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterAndSetterConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+bool setJSTestNamedSetterWithIndexedGetterAndSetterConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
+
+class JSTestNamedSetterWithIndexedGetterAndSetterPrototype : public JSC::JSNonFinalObject {
+public:
+ using Base = JSC::JSNonFinalObject;
+ static JSTestNamedSetterWithIndexedGetterAndSetterPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
+ {
+ JSTestNamedSetterWithIndexedGetterAndSetterPrototype* ptr = new (NotNull, JSC::allocateCell<JSTestNamedSetterWithIndexedGetterAndSetterPrototype>(vm.heap)) JSTestNamedSetterWithIndexedGetterAndSetterPrototype(vm, globalObject, structure);
+ ptr->finishCreation(vm);
+ return ptr;
+ }
+
+ DECLARE_INFO;
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
+private:
+ JSTestNamedSetterWithIndexedGetterAndSetterPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
+ : JSC::JSNonFinalObject(vm, structure)
+ {
+ }
+
+ void finishCreation(JSC::VM&);
+};
+
+using JSTestNamedSetterWithIndexedGetterAndSetterConstructor = JSDOMConstructorNotConstructable<JSTestNamedSetterWithIndexedGetterAndSetter>;
+
+template<> JSValue JSTestNamedSetterWithIndexedGetterAndSetterConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
+{
+ UNUSED_PARAM(vm);
+ return globalObject.functionPrototype();
+}
+
+template<> void JSTestNamedSetterWithIndexedGetterAndSetterConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ putDirect(vm, vm.propertyNames->prototype, JSTestNamedSetterWithIndexedGetterAndSetter::prototype(vm, globalObject), DontDelete | ReadOnly | DontEnum);
+ putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("TestNamedSetterWithIndexedGetterAndSetter"))), ReadOnly | DontEnum);
+ putDirect(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum);
+}
+
+template<> const ClassInfo JSTestNamedSetterWithIndexedGetterAndSetterConstructor::s_info = { "TestNamedSetterWithIndexedGetterAndSetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestNamedSetterWithIndexedGetterAndSetterConstructor) };
+
+/* Hash table for prototype */
+
+static const HashTableValue JSTestNamedSetterWithIndexedGetterAndSetterPrototypeTableValues[] =
+{
+ { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestNamedSetterWithIndexedGetterAndSetterConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestNamedSetterWithIndexedGetterAndSetterConstructor) } },
+ { "namedSetter", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionNamedSetter), (intptr_t) (2) } },
+ { "indexedSetter", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetter), (intptr_t) (1) } },
+};
+
+const ClassInfo JSTestNamedSetterWithIndexedGetterAndSetterPrototype::s_info = { "TestNamedSetterWithIndexedGetterAndSetterPrototype", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestNamedSetterWithIndexedGetterAndSetterPrototype) };
+
+void JSTestNamedSetterWithIndexedGetterAndSetterPrototype::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ reifyStaticProperties(vm, JSTestNamedSetterWithIndexedGetterAndSetterPrototypeTableValues, *this);
+}
+
+const ClassInfo JSTestNamedSetterWithIndexedGetterAndSetter::s_info = { "TestNamedSetterWithIndexedGetterAndSetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestNamedSetterWithIndexedGetterAndSetter) };
+
+JSTestNamedSetterWithIndexedGetterAndSetter::JSTestNamedSetterWithIndexedGetterAndSetter(Structure* structure, JSDOMGlobalObject& globalObject, Ref<TestNamedSetterWithIndexedGetterAndSetter>&& impl)
+ : JSDOMWrapper<TestNamedSetterWithIndexedGetterAndSetter>(structure, globalObject, WTFMove(impl))
+{
+}
+
+void JSTestNamedSetterWithIndexedGetterAndSetter::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(vm, info()));
+
+}
+
+JSObject* JSTestNamedSetterWithIndexedGetterAndSetter::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ return JSTestNamedSetterWithIndexedGetterAndSetterPrototype::create(vm, &globalObject, JSTestNamedSetterWithIndexedGetterAndSetterPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
+}
+
+JSObject* JSTestNamedSetterWithIndexedGetterAndSetter::prototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ return getDOMPrototype<JSTestNamedSetterWithIndexedGetterAndSetter>(vm, globalObject);
+}
+
+JSValue JSTestNamedSetterWithIndexedGetterAndSetter::getConstructor(VM& vm, const JSGlobalObject* globalObject)
+{
+ return getDOMConstructor<JSTestNamedSetterWithIndexedGetterAndSetterConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
+}
+
+void JSTestNamedSetterWithIndexedGetterAndSetter::destroy(JSC::JSCell* cell)
+{
+ JSTestNamedSetterWithIndexedGetterAndSetter* thisObject = static_cast<JSTestNamedSetterWithIndexedGetterAndSetter*>(cell);
+ thisObject->JSTestNamedSetterWithIndexedGetterAndSetter::~JSTestNamedSetterWithIndexedGetterAndSetter();
+}
+
+bool JSTestNamedSetterWithIndexedGetterAndSetter::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot& slot)
+{
+ auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetterAndSetter*>(object);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ if (auto index = parseIndex(propertyName)) {
+ if (index.value() < thisObject->wrapped().length()) {
+ auto value = toJS<IDLDOMString>(*state, thisObject->wrapped().indexedSetter(index.value()));
+ slot.setValue(thisObject, 0, value);
+ return true;
+ }
+ return JSObject::getOwnPropertySlot(object, state, propertyName, slot);
+ }
+ using GetterIDLType = IDLDOMString;
+ auto getterFunctor = [] (auto& thisObject, auto propertyName) -> std::optional<typename GetterIDLType::ImplementationType> {
+ auto result = thisObject.wrapped().namedItem(propertyNameToAtomicString(propertyName));
+ if (!GetterIDLType::isNullValue(result))
+ return typename GetterIDLType::ImplementationType { GetterIDLType::extractValueFromNullable(result) };
+ return std::nullopt;
+ };
+ if (auto namedProperty = accessVisibleNamedProperty<OverrideBuiltins::No>(*state, *thisObject, propertyName, getterFunctor)) {
+ auto value = toJS<IDLDOMString>(*state, WTFMove(namedProperty.value()));
+ slot.setValue(thisObject, 0, value);
+ return true;
+ }
+ return JSObject::getOwnPropertySlot(object, state, propertyName, slot);
+}
+
+bool JSTestNamedSetterWithIndexedGetterAndSetter::getOwnPropertySlotByIndex(JSObject* object, ExecState* state, unsigned index, PropertySlot& slot)
+{
+ auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetterAndSetter*>(object);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ if (LIKELY(index <= MAX_ARRAY_INDEX)) {
+ if (index < thisObject->wrapped().length()) {
+ auto value = toJS<IDLDOMString>(*state, thisObject->wrapped().indexedSetter(index));
+ slot.setValue(thisObject, 0, value);
+ return true;
+ }
+ return JSObject::getOwnPropertySlotByIndex(object, state, index, slot);
+ }
+ auto propertyName = Identifier::from(state, index);
+ using GetterIDLType = IDLDOMString;
+ auto getterFunctor = [] (auto& thisObject, auto propertyName) -> std::optional<typename GetterIDLType::ImplementationType> {
+ auto result = thisObject.wrapped().namedItem(propertyNameToAtomicString(propertyName));
+ if (!GetterIDLType::isNullValue(result))
+ return typename GetterIDLType::ImplementationType { GetterIDLType::extractValueFromNullable(result) };
+ return std::nullopt;
+ };
+ if (auto namedProperty = accessVisibleNamedProperty<OverrideBuiltins::No>(*state, *thisObject, propertyName, getterFunctor)) {
+ auto value = toJS<IDLDOMString>(*state, WTFMove(namedProperty.value()));
+ slot.setValue(thisObject, 0, value);
+ return true;
+ }
+ return JSObject::getOwnPropertySlotByIndex(object, state, index, slot);
+}
+
+void JSTestNamedSetterWithIndexedGetterAndSetter::getOwnPropertyNames(JSObject* object, ExecState* state, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+ auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetterAndSetter*>(object);
+ ASSERT_GC_OBJECT_INHERITS(object, info());
+ for (unsigned i = 0, count = thisObject->wrapped().length(); i < count; ++i)
+ propertyNames.add(Identifier::from(state, i));
+ for (auto& propertyName : thisObject->wrapped().supportedPropertyNames())
+ propertyNames.add(Identifier::fromString(state, propertyName));
+ JSObject::getOwnPropertyNames(object, state, propertyNames, mode);
+}
+
+bool JSTestNamedSetterWithIndexedGetterAndSetter::put(JSCell* cell, ExecState* state, PropertyName propertyName, JSValue value, PutPropertySlot& putPropertySlot)
+{
+ auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetterAndSetter*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+
+ if (auto index = parseIndex(propertyName)) {
+ auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+ auto nativeValue = convert<IDLDOMString>(*state, value);
+ RETURN_IF_EXCEPTION(throwScope, true);
+ thisObject->wrapped().indexedSetter(index.value(), WTFMove(nativeValue));
+ return true;
+ }
+
+ if (!propertyName.isSymbol()) {
+ PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
+ JSValue prototype = thisObject->getPrototypeDirect();
+ if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
+ auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+ auto nativeValue = convert<IDLDOMString>(*state, value);
+ RETURN_IF_EXCEPTION(throwScope, true);
+ thisObject->wrapped().namedSetter(propertyNameToString(propertyName), WTFMove(nativeValue));
+ return true;
+ }
+ }
+
+ return JSObject::put(thisObject, state, propertyName, value, putPropertySlot);
+}
+
+bool JSTestNamedSetterWithIndexedGetterAndSetter::putByIndex(JSCell* cell, ExecState* state, unsigned index, JSValue value, bool shouldThrow)
+{
+ auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetterAndSetter*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+
+ if (LIKELY(index <= MAX_ARRAY_INDEX)) {
+ auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+ auto nativeValue = convert<IDLDOMString>(*state, value);
+ RETURN_IF_EXCEPTION(throwScope, true);
+ thisObject->wrapped().indexedSetter(index, WTFMove(nativeValue));
+ return true;
+ }
+
+ auto propertyName = Identifier::from(state, index);
+ PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
+ JSValue prototype = thisObject->getPrototypeDirect();
+ if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
+ auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+ auto nativeValue = convert<IDLDOMString>(*state, value);
+ RETURN_IF_EXCEPTION(throwScope, true);
+ thisObject->wrapped().namedSetter(propertyNameToString(propertyName), WTFMove(nativeValue));
+ return true;
+ }
+
+ return JSObject::putByIndex(cell, state, index, value, shouldThrow);
+}
+
+bool JSTestNamedSetterWithIndexedGetterAndSetter::defineOwnProperty(JSObject* object, ExecState* state, PropertyName propertyName, const PropertyDescriptor& propertyDescriptor, bool shouldThrow)
+{
+ auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetterAndSetter*>(object);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+
+ if (auto index = parseIndex(propertyName)) {
+ if (!propertyDescriptor.isDataDescriptor())
+ return false;
+ auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+ auto nativeValue = convert<IDLDOMString>(*state, propertyDescriptor.value());
+ RETURN_IF_EXCEPTION(throwScope, true);
+ thisObject->wrapped().indexedSetter(index.value(), WTFMove(nativeValue));
+ return true;
+ }
+
+ if (!propertyName.isSymbol()) {
+ PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
+ if (!JSObject::getOwnPropertySlot(thisObject, state, propertyName, slot)) {
+ if (!propertyDescriptor.isDataDescriptor())
+ return false;
+ auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+ auto nativeValue = convert<IDLDOMString>(*state, propertyDescriptor.value());
+ RETURN_IF_EXCEPTION(throwScope, true);
+ thisObject->wrapped().namedSetter(propertyNameToString(propertyName), WTFMove(nativeValue));
+ return true;
+ }
+ }
+
+ PropertyDescriptor newPropertyDescriptor = propertyDescriptor;
+ newPropertyDescriptor.setConfigurable(true);
+ return JSObject::defineOwnProperty(object, state, propertyName, newPropertyDescriptor, shouldThrow);
+}
+
+template<> inline JSTestNamedSetterWithIndexedGetterAndSetter* IDLOperation<JSTestNamedSetterWithIndexedGetterAndSetter>::cast(ExecState& state)
+{
+ return jsDynamicDowncast<JSTestNamedSetterWithIndexedGetterAndSetter*>(state.vm(), state.thisValue());
+}
+
+EncodedJSValue jsTestNamedSetterWithIndexedGetterAndSetterConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+ VM& vm = state->vm();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ auto* prototype = jsDynamicDowncast<JSTestNamedSetterWithIndexedGetterAndSetterPrototype*>(vm, JSValue::decode(thisValue));
+ if (UNLIKELY(!prototype))
+ return throwVMTypeError(state, throwScope);
+ return JSValue::encode(JSTestNamedSetterWithIndexedGetterAndSetter::getConstructor(state->vm(), prototype->globalObject()));
+}
+
+bool setJSTestNamedSetterWithIndexedGetterAndSetterConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
+{
+ VM& vm = state->vm();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ auto* prototype = jsDynamicDowncast<JSTestNamedSetterWithIndexedGetterAndSetterPrototype*>(vm, JSValue::decode(thisValue));
+ if (UNLIKELY(!prototype)) {
+ throwVMTypeError(state, throwScope);
+ return false;
+ }
+ // Shadowing a built-in constructor
+ return prototype->putDirect(state->vm(), state->propertyNames().constructor, JSValue::decode(encodedValue));
+}
+
+static inline JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionNamedSetterBody(JSC::ExecState* state, typename IDLOperation<JSTestNamedSetterWithIndexedGetterAndSetter>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+ UNUSED_PARAM(state);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(state->argumentCount() < 2))
+ return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+ auto name = convert<IDLDOMString>(*state, state->uncheckedArgument(0));
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ auto value = convert<IDLDOMString>(*state, state->uncheckedArgument(1));
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ impl.namedSetter(WTFMove(name), WTFMove(value));
+ return JSValue::encode(jsUndefined());
+}
+
+EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionNamedSetter(ExecState* state)
+{
+ return IDLOperation<JSTestNamedSetterWithIndexedGetterAndSetter>::call<jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionNamedSetterBody>(*state, "namedSetter");
+}
+
+static inline JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetter1Body(JSC::ExecState* state, typename IDLOperation<JSTestNamedSetterWithIndexedGetterAndSetter>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+ UNUSED_PARAM(state);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ auto index = convert<IDLUnsignedLong>(*state, state->uncheckedArgument(0));
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ auto value = convert<IDLDOMString>(*state, state->uncheckedArgument(1));
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ impl.indexedSetter(WTFMove(index), WTFMove(value));
+ return JSValue::encode(jsUndefined());
+}
+
+static inline JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetter2Body(JSC::ExecState* state, typename IDLOperation<JSTestNamedSetterWithIndexedGetterAndSetter>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+ UNUSED_PARAM(state);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ auto index = convert<IDLUnsignedLong>(*state, state->uncheckedArgument(0));
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ return JSValue::encode(toJS<IDLDOMString>(*state, impl.indexedSetter(WTFMove(index))));
+}
+
+static inline JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetterOverloadDispatcher(JSC::ExecState* state, typename IDLOperation<JSTestNamedSetterWithIndexedGetterAndSetter>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+ UNUSED_PARAM(state);
+ UNUSED_PARAM(throwScope);
+ VM& vm = state->vm();
+ UNUSED_PARAM(vm);
+ size_t argsCount = std::min<size_t>(2, state->argumentCount());
+ if (argsCount == 1) {
+ return jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetter2Body(state, castedThis, throwScope);
+ }
+ if (argsCount == 2) {
+ return jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetter1Body(state, castedThis, throwScope);
+ }
+ return argsCount < 1 ? throwVMError(state, throwScope, createNotEnoughArgumentsError(state)) : throwVMTypeError(state, throwScope);
+}
+
+EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetter(ExecState* state)
+{
+ return IDLOperation<JSTestNamedSetterWithIndexedGetterAndSetter>::call<jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetterOverloadDispatcher>(*state, "indexedSetter");
+}
+
+bool JSTestNamedSetterWithIndexedGetterAndSetterOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
+{
+ UNUSED_PARAM(handle);
+ UNUSED_PARAM(visitor);
+ return false;
+}
+
+void JSTestNamedSetterWithIndexedGetterAndSetterOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
+{
+ auto* jsTestNamedSetterWithIndexedGetterAndSetter = static_cast<JSTestNamedSetterWithIndexedGetterAndSetter*>(handle.slot()->asCell());
+ auto& world = *static_cast<DOMWrapperWorld*>(context);
+ uncacheWrapper(world, &jsTestNamedSetterWithIndexedGetterAndSetter->wrapped(), jsTestNamedSetterWithIndexedGetterAndSetter);
+}
+
+#if ENABLE(BINDING_INTEGRITY)
+#if PLATFORM(WIN)
+#pragma warning(disable: 4483)
+extern "C" { extern void (*const __identifier("??_7TestNamedSetterWithIndexedGetterAndSetter@WebCore@@6B@")[])(); }
+#else
+extern "C" { extern void* _ZTVN7WebCore41TestNamedSetterWithIndexedGetterAndSetterE[]; }
+#endif
+#endif
+
+JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<TestNamedSetterWithIndexedGetterAndSetter>&& impl)
+{
+
+#if ENABLE(BINDING_INTEGRITY)
+ void* actualVTablePointer = *(reinterpret_cast<void**>(impl.ptr()));
+#if PLATFORM(WIN)
+ void* expectedVTablePointer = reinterpret_cast<void*>(__identifier("??_7TestNamedSetterWithIndexedGetterAndSetter@WebCore@@6B@"));
+#else
+ void* expectedVTablePointer = &_ZTVN7WebCore41TestNamedSetterWithIndexedGetterAndSetterE[2];
+#endif
+
+ // If this fails TestNamedSetterWithIndexedGetterAndSetter does not have a vtable, so you need to add the
+ // ImplementationLacksVTable attribute to the interface definition
+ static_assert(std::is_polymorphic<TestNamedSetterWithIndexedGetterAndSetter>::value, "TestNamedSetterWithIndexedGetterAndSetter is not polymorphic");
+
+ // If you hit this assertion you either have a use after free bug, or
+ // TestNamedSetterWithIndexedGetterAndSetter has subclasses. If TestNamedSetterWithIndexedGetterAndSetter has subclasses that get passed
+ // to toJS() we currently require TestNamedSetterWithIndexedGetterAndSetter you to opt out of binding hardening
+ // by adding the SkipVTableValidation attribute to the interface IDL definition
+ RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
+#endif
+ return createWrapper<TestNamedSetterWithIndexedGetterAndSetter>(globalObject, WTFMove(impl));
+}
+
+JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, TestNamedSetterWithIndexedGetterAndSetter& impl)
+{
+ return wrap(state, globalObject, impl);
+}
+
+TestNamedSetterWithIndexedGetterAndSetter* JSTestNamedSetterWithIndexedGetterAndSetter::toWrapped(JSC::VM& vm, JSC::JSValue value)
+{
+ if (auto* wrapper = jsDynamicDowncast<JSTestNamedSetterWithIndexedGetterAndSetter*>(vm, value))
+ return &wrapper->wrapped();
+ return nullptr;
+}
+
+}
Added: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.h (0 => 219622)
--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.h (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.h 2017-07-18 20:12:15 UTC (rev 219622)
@@ -0,0 +1,93 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#include "JSDOMWrapper.h"
+#include "TestNamedSetterWithIndexedGetterAndSetter.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+class JSTestNamedSetterWithIndexedGetterAndSetter : public JSDOMWrapper<TestNamedSetterWithIndexedGetterAndSetter> {
+public:
+ using Base = JSDOMWrapper<TestNamedSetterWithIndexedGetterAndSetter>;
+ static JSTestNamedSetterWithIndexedGetterAndSetter* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<TestNamedSetterWithIndexedGetterAndSetter>&& impl)
+ {
+ JSTestNamedSetterWithIndexedGetterAndSetter* ptr = new (NotNull, JSC::allocateCell<JSTestNamedSetterWithIndexedGetterAndSetter>(globalObject->vm().heap)) JSTestNamedSetterWithIndexedGetterAndSetter(structure, *globalObject, WTFMove(impl));
+ ptr->finishCreation(globalObject->vm());
+ return ptr;
+ }
+
+ static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
+ static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
+ static TestNamedSetterWithIndexedGetterAndSetter* toWrapped(JSC::VM&, JSC::JSValue);
+ static bool getOwnPropertySlot(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName, JSC::PropertySlot&);
+ static bool getOwnPropertySlotByIndex(JSC::JSObject*, JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
+ static void getOwnPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode = JSC::EnumerationMode());
+ static bool put(JSC::JSCell*, JSC::ExecState*, JSC::PropertyName, JSC::JSValue, JSC::PutPropertySlot&);
+ static bool putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue, bool shouldThrow);
+ static bool defineOwnProperty(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName, const JSC::PropertyDescriptor&, bool shouldThrow);
+ static void destroy(JSC::JSCell*);
+
+ DECLARE_INFO;
+
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
+ static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
+public:
+ static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
+protected:
+ JSTestNamedSetterWithIndexedGetterAndSetter(JSC::Structure*, JSDOMGlobalObject&, Ref<TestNamedSetterWithIndexedGetterAndSetter>&&);
+
+ void finishCreation(JSC::VM&);
+};
+
+class JSTestNamedSetterWithIndexedGetterAndSetterOwner : public JSC::WeakHandleOwner {
+public:
+ virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
+ virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
+};
+
+inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, TestNamedSetterWithIndexedGetterAndSetter*)
+{
+ static NeverDestroyed<JSTestNamedSetterWithIndexedGetterAndSetterOwner> owner;
+ return &owner.get();
+}
+
+inline void* wrapperKey(TestNamedSetterWithIndexedGetterAndSetter* wrappableObject)
+{
+ return wrappableObject;
+}
+
+JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, TestNamedSetterWithIndexedGetterAndSetter&);
+inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, TestNamedSetterWithIndexedGetterAndSetter* impl) { return impl ? toJS(state, globalObject, *impl) : JSC::jsNull(); }
+JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject*, Ref<TestNamedSetterWithIndexedGetterAndSetter>&&);
+inline JSC::JSValue toJSNewlyCreated(JSC::ExecState* state, JSDOMGlobalObject* globalObject, RefPtr<TestNamedSetterWithIndexedGetterAndSetter>&& impl) { return impl ? toJSNewlyCreated(state, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
+
+template<> struct JSDOMWrapperConverterTraits<TestNamedSetterWithIndexedGetterAndSetter> {
+ using WrapperClass = JSTestNamedSetterWithIndexedGetterAndSetter;
+ using ToWrappedReturnType = TestNamedSetterWithIndexedGetterAndSetter*;
+};
+
+} // namespace WebCore
Added: trunk/Source/WebCore/bindings/scripts/test/TestNamedSetterWithIndexedGetter.idl (0 => 219622)
--- trunk/Source/WebCore/bindings/scripts/test/TestNamedSetterWithIndexedGetter.idl (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/TestNamedSetterWithIndexedGetter.idl 2017-07-18 20:12:15 UTC (rev 219622)
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+interface TestNamedSetterWithIndexedGetter {
+ setter void namedSetter(DOMString name, DOMString value);
+ getter DOMString (DOMString name);
+
+ getter DOMString indexedSetter(unsigned long index);
+};
Added: trunk/Source/WebCore/bindings/scripts/test/TestNamedSetterWithIndexedGetterAndSetter.idl (0 => 219622)
--- trunk/Source/WebCore/bindings/scripts/test/TestNamedSetterWithIndexedGetterAndSetter.idl (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/TestNamedSetterWithIndexedGetterAndSetter.idl 2017-07-18 20:12:15 UTC (rev 219622)
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+interface TestNamedSetterWithIndexedGetterAndSetter {
+ setter void namedSetter(DOMString name, DOMString value);
+ getter DOMString (DOMString name);
+
+ setter void indexedSetter(unsigned long index, DOMString value);
+ getter DOMString indexedSetter(unsigned long index);
+};
Modified: trunk/Source/WebCore/css/CSSAllInOne.cpp (219621 => 219622)
--- trunk/Source/WebCore/css/CSSAllInOne.cpp 2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/css/CSSAllInOne.cpp 2017-07-18 20:12:15 UTC (rev 219622)
@@ -78,6 +78,7 @@
#include "CSSSelector.cpp"
#include "CSSSelectorList.cpp"
#include "CSSShadowValue.cpp"
+#include "CSSStyleDeclaration.cpp"
#include "CSSStyleRule.cpp"
#include "CSSStyleSheet.cpp"
#include "CSSSupportsRule.cpp"
Added: trunk/Source/WebCore/css/CSSStyleDeclaration.cpp (0 => 219622)
--- trunk/Source/WebCore/css/CSSStyleDeclaration.cpp (rev 0)
+++ trunk/Source/WebCore/css/CSSStyleDeclaration.cpp 2017-07-18 20:12:15 UTC (rev 219622)
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CSSStyleDeclaration.h"
+
+#include "CSSPropertyNames.h"
+#include "CSSPropertyParser.h"
+#include "HashTools.h"
+#include "RuntimeEnabledFeatures.h"
+#include "Settings.h"
+
+namespace WebCore {
+
+namespace {
+
+enum class PropertyNamePrefix {
+ None, Epub, CSS, Pixel, Pos, WebKit,
+#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
+ Apple, KHTML,
+#endif
+};
+
+template<size_t prefixCStringLength>
+static inline bool matchesCSSPropertyNamePrefix(const StringImpl& propertyName, const char (&prefix)[prefixCStringLength])
+{
+ size_t prefixLength = prefixCStringLength - 1;
+
+ ASSERT(toASCIILower(propertyName[0]) == prefix[0]);
+ const size_t offset = 1;
+
+#ifndef NDEBUG
+ for (size_t i = 0; i < prefixLength; ++i)
+ ASSERT(isASCIILower(prefix[i]));
+ ASSERT(!prefix[prefixLength]);
+ ASSERT(propertyName.length());
+#endif
+
+ // The prefix within the property name must be followed by a capital letter.
+ // Other characters in the prefix within the property name must be lowercase.
+ if (propertyName.length() < prefixLength + 1)
+ return false;
+
+ for (size_t i = offset; i < prefixLength; ++i) {
+ if (propertyName[i] != prefix[i])
+ return false;
+ }
+
+ if (!isASCIIUpper(propertyName[prefixLength]))
+ return false;
+
+ return true;
+}
+
+static PropertyNamePrefix propertyNamePrefix(const StringImpl& propertyName)
+{
+ ASSERT(propertyName.length());
+
+ // First character of the prefix within the property name may be upper or lowercase.
+ UChar firstChar = toASCIILower(propertyName[0]);
+ switch (firstChar) {
+#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
+ case 'a':
+ if (RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled() && matchesCSSPropertyNamePrefix(propertyName, "apple"))
+ return PropertyNamePrefix::Apple;
+ break;
+#endif
+ case 'c':
+ if (matchesCSSPropertyNamePrefix(propertyName, "css"))
+ return PropertyNamePrefix::CSS;
+ break;
+#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
+ case 'k':
+ if (RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled() && matchesCSSPropertyNamePrefix(propertyName, "khtml"))
+ return PropertyNamePrefix::KHTML;
+ break;
+#endif
+ case 'e':
+ if (matchesCSSPropertyNamePrefix(propertyName, "epub"))
+ return PropertyNamePrefix::Epub;
+ break;
+ case 'p':
+ if (matchesCSSPropertyNamePrefix(propertyName, "pos"))
+ return PropertyNamePrefix::Pos;
+ if (matchesCSSPropertyNamePrefix(propertyName, "pixel"))
+ return PropertyNamePrefix::Pixel;
+ break;
+ case 'w':
+ if (matchesCSSPropertyNamePrefix(propertyName, "webkit"))
+ return PropertyNamePrefix::WebKit;
+ break;
+ default:
+ break;
+ }
+ return PropertyNamePrefix::None;
+}
+
+static inline void writeWebKitPrefix(char*& buffer)
+{
+ *buffer++ = '-';
+ *buffer++ = 'w';
+ *buffer++ = 'e';
+ *buffer++ = 'b';
+ *buffer++ = 'k';
+ *buffer++ = 'i';
+ *buffer++ = 't';
+ *buffer++ = '-';
+}
+
+static inline void writeEpubPrefix(char*& buffer)
+{
+ *buffer++ = '-';
+ *buffer++ = 'e';
+ *buffer++ = 'p';
+ *buffer++ = 'u';
+ *buffer++ = 'b';
+ *buffer++ = '-';
+}
+
+struct CSSPropertyInfo {
+ CSSPropertyID propertyID;
+ bool hadPixelOrPosPrefix;
+};
+
+static CSSPropertyInfo parseJavaScriptCSSPropertyName(const AtomicString& propertyName)
+{
+ using CSSPropertyInfoMap = HashMap<String, CSSPropertyInfo>;
+ static NeverDestroyed<CSSPropertyInfoMap> propertyInfoCache;
+
+ CSSPropertyInfo propertyInfo = { CSSPropertyInvalid, false };
+
+ auto* propertyNameString = propertyName.impl();
+ if (!propertyNameString)
+ return propertyInfo;
+ unsigned length = propertyNameString->length();
+ if (!length)
+ return propertyInfo;
+
+ propertyInfo = propertyInfoCache.get().get(propertyNameString);
+ if (propertyInfo.propertyID)
+ return propertyInfo;
+
+ bool hadPixelOrPosPrefix = false;
+
+ constexpr size_t bufferSize = maxCSSPropertyNameLength + 1;
+ char buffer[bufferSize];
+ char* bufferPtr = buffer;
+ const char* name = bufferPtr;
+
+ unsigned i = 0;
+ // Prefixes CSS, Pixel, Pos are ignored.
+ // Prefixes Apple, KHTML and Webkit are transposed to "-webkit-".
+ // The prefix "Epub" becomes "-epub-".
+ switch (propertyNamePrefix(*propertyNameString)) {
+ case PropertyNamePrefix::None:
+ if (isASCIIUpper((*propertyNameString)[0]))
+ return propertyInfo;
+ break;
+ case PropertyNamePrefix::CSS:
+ i += 3;
+ break;
+ case PropertyNamePrefix::Pixel:
+ i += 5;
+ hadPixelOrPosPrefix = true;
+ break;
+ case PropertyNamePrefix::Pos:
+ i += 3;
+ hadPixelOrPosPrefix = true;
+ break;
+#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
+ case PropertyNamePrefix::Apple:
+ case PropertyNamePrefix::KHTML:
+ ASSERT(RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled());
+ writeWebKitPrefix(bufferPtr);
+ i += 5;
+ break;
+#endif
+ case PropertyNamePrefix::Epub:
+ writeEpubPrefix(bufferPtr);
+ i += 4;
+ break;
+ case PropertyNamePrefix::WebKit:
+ writeWebKitPrefix(bufferPtr);
+ i += 6;
+ break;
+ }
+
+ *bufferPtr++ = toASCIILower((*propertyNameString)[i++]);
+
+ char* bufferEnd = buffer + bufferSize;
+ char* stringEnd = bufferEnd - 1;
+ size_t bufferSizeLeft = stringEnd - bufferPtr;
+ size_t propertySizeLeft = length - i;
+ if (propertySizeLeft > bufferSizeLeft)
+ return propertyInfo;
+
+ for (; i < length; ++i) {
+ UChar c = (*propertyNameString)[i];
+ if (!c || !isASCII(c))
+ return propertyInfo; // illegal character
+ if (isASCIIUpper(c)) {
+ size_t bufferSizeLeft = stringEnd - bufferPtr;
+ size_t propertySizeLeft = length - i + 1;
+ if (propertySizeLeft > bufferSizeLeft)
+ return propertyInfo;
+ *bufferPtr++ = '-';
+ *bufferPtr++ = toASCIILowerUnchecked(c);
+ } else
+ *bufferPtr++ = c;
+ ASSERT_WITH_SECURITY_IMPLICATION(bufferPtr < bufferEnd);
+ }
+ ASSERT_WITH_SECURITY_IMPLICATION(bufferPtr < bufferEnd);
+ *bufferPtr = '\0';
+
+ unsigned outputLength = bufferPtr - buffer;
+#if PLATFORM(IOS)
+ cssPropertyNameIOSAliasing(buffer, name, outputLength);
+#endif
+
+ auto* hashTableEntry = findProperty(name, outputLength);
+ if (auto propertyID = hashTableEntry ? hashTableEntry->id : 0) {
+ propertyInfo.hadPixelOrPosPrefix = hadPixelOrPosPrefix;
+ propertyInfo.propertyID = static_cast<CSSPropertyID>(propertyID);
+ propertyInfoCache.get().add(propertyNameString, propertyInfo);
+ }
+ return propertyInfo;
+}
+
+}
+
+std::optional<Variant<String, double>> CSSStyleDeclaration::namedItem(const AtomicString& propertyName)
+{
+ auto propertyInfo = parseJavaScriptCSSPropertyName(propertyName);
+ if (!propertyInfo.propertyID)
+ return std::nullopt;
+
+ auto value = getPropertyCSSValueInternal(propertyInfo.propertyID);
+ if (!value) {
+ // If the property is a shorthand property (such as "padding"), it can only be accessed using getPropertyValue.
+ return Variant<String, double> { getPropertyValueInternal(propertyInfo.propertyID) };
+ }
+
+ if (propertyInfo.hadPixelOrPosPrefix && is<CSSPrimitiveValue>(*value)) {
+ // Call this version of the getter so that, e.g., pixelTop returns top as a number
+ // in pixel units and posTop should does the same _if_ this is a positioned element.
+ // FIXME: If not a positioned element, MSIE documentation says posTop should return 0; this rule is not implemented.
+ return Variant<String, double> { downcast<CSSPrimitiveValue>(*value).floatValue(CSSPrimitiveValue::CSS_PX) };
+ }
+
+ return Variant<String, double> { value->cssText() };
+}
+
+ExceptionOr<void> CSSStyleDeclaration::setNamedItem(const AtomicString& propertyName, String value, bool& propertySupported)
+{
+ auto propertyInfo = parseJavaScriptCSSPropertyName(propertyName);
+ if (!propertyInfo.propertyID) {
+ propertySupported = false;
+ return { };
+ }
+
+ propertySupported = true;
+
+ if (propertyInfo.hadPixelOrPosPrefix)
+ value.append("px");
+
+ bool important = false;
+ if (Settings::shouldRespectPriorityInCSSAttributeSetters()) {
+ auto importantIndex = value.findIgnoringASCIICase("!important");
+ if (importantIndex && importantIndex != notFound) {
+ important = true;
+ value = value.left(importantIndex - 1);
+ }
+ }
+
+ auto setPropertyInternalResult = setPropertyInternal(propertyInfo.propertyID, value, important);
+ if (setPropertyInternalResult.hasException())
+ return setPropertyInternalResult.releaseException();
+
+ return { };
+}
+
+Vector<AtomicString> CSSStyleDeclaration::supportedPropertyNames() const
+{
+ static const AtomicString* const cssPropertyNames = [] {
+ String names[numCSSProperties];
+ for (int i = 0; i < numCSSProperties; ++i)
+ names[i] = getJSPropertyName(static_cast<CSSPropertyID>(firstCSSProperty + i));
+ std::sort(&names[0], &names[numCSSProperties], WTF::codePointCompareLessThan);
+ auto* identifiers = new AtomicString[numCSSProperties];
+ for (int i = 0; i < numCSSProperties; ++i)
+ identifiers[i] = names[i];
+ return identifiers;
+ }();
+
+ Vector<AtomicString> result;
+ result.reserveInitialCapacity(numCSSProperties);
+
+ for (unsigned i = 0; i < numCSSProperties; ++i)
+ result.uncheckedAppend(cssPropertyNames[i]);
+
+ return result;
+}
+
+}
Modified: trunk/Source/WebCore/css/CSSStyleDeclaration.h (219621 => 219622)
--- trunk/Source/WebCore/css/CSSStyleDeclaration.h 2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/css/CSSStyleDeclaration.h 2017-07-18 20:12:15 UTC (rev 219622)
@@ -25,6 +25,8 @@
#include "ExceptionOr.h"
#include "ScriptWrappable.h"
#include <wtf/Forward.h>
+#include <wtf/Optional.h>
+#include <wtf/Variant.h>
namespace WebCore {
@@ -69,6 +71,11 @@
virtual CSSStyleSheet* parentStyleSheet() const { return nullptr; }
+ // Bindings support.
+ std::optional<Variant<String, double>> namedItem(const AtomicString&);
+ ExceptionOr<void> setNamedItem(const AtomicString& name, String value, bool& propertySupported);
+ Vector<AtomicString> supportedPropertyNames() const;
+
protected:
CSSStyleDeclaration() { }
};
Modified: trunk/Source/WebCore/css/CSSStyleDeclaration.idl (219621 => 219622)
--- trunk/Source/WebCore/css/CSSStyleDeclaration.idl 2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/css/CSSStyleDeclaration.idl 2017-07-18 20:12:15 UTC (rev 219622)
@@ -19,10 +19,8 @@
*/
[
- CustomGetOwnPropertyNames,
- CustomGetOwnPropertySlotAndDescriptor,
- CustomPut,
ExportMacro=WEBCORE_EXPORT,
+ DefaultDefineOwnProperty,
GenerateIsReachable,
JSCustomHeader,
JSCustomMarkFunction,
@@ -32,9 +30,6 @@
DOMString getPropertyValue(DOMString propertyName);
- // This method is deprecated, and we would like to drop support for it someday
- [Custom] DeprecatedCSSOMValue? getPropertyCSSValue(DOMString propertyName);
-
[CEReactions, MayThrowException] DOMString removeProperty(DOMString propertyName);
DOMString? getPropertyPriority(DOMString propertyName);
@@ -47,4 +42,14 @@
// FIXME: Using "undefined" as default parameter value is wrong.
DOMString? getPropertyShorthand(optional DOMString propertyName = "undefined");
boolean isPropertyImplicit(optional DOMString propertyName = "undefined");
+
+ // Use named getters/setters for all support CSS property names. The spec says
+ // these should be normal attributes, but there are too many combinations with
+ // prefixes for this to be practical. If we remove legacy aliases, we should
+ // reconsider this decision.
+ getter (DOMString or double) (DOMString name);
+ [CEReactions, MayThrowException, CallNamedSetterOnlyForSupportedProperties] setter void (DOMString name, [TreatNullAs=EmptyString] DOMString value);
+
+ // This method is deprecated, and we would like to drop support for it someday
+ [Custom] DeprecatedCSSOMValue? getPropertyCSSValue(DOMString propertyName);
};