Diff
Modified: trunk/LayoutTests/ChangeLog (200906 => 200907)
--- trunk/LayoutTests/ChangeLog 2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/LayoutTests/ChangeLog 2016-05-14 02:10:27 UTC (rev 200907)
@@ -1,3 +1,17 @@
+2016-05-13 Chris Dumez <[email protected]>
+
+ Align window.scroll() / scrollTo() / scrollBy() with the CSSOM specification
+ https://bugs.webkit.org/show_bug.cgi?id=157666
+
+ Reviewed by Darin Adler.
+
+ Update / improve testing coverage for the API.
+
+ * fast/dom/Window/window-scroll-arguments-expected.txt:
+ * fast/dom/Window/window-scroll-arguments.html:
+ * fast/dom/non-numeric-values-numeric-parameters-expected.txt:
+ * fast/dom/script-tests/non-numeric-values-numeric-parameters.js:
+
2016-05-13 Simon Fraser <[email protected]>
cross-fade() rendering doesn't match expectation
Modified: trunk/LayoutTests/fast/dom/Window/window-scroll-arguments-expected.txt (200906 => 200907)
--- trunk/LayoutTests/fast/dom/Window/window-scroll-arguments-expected.txt 2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/LayoutTests/fast/dom/Window/window-scroll-arguments-expected.txt 2016-05-14 02:10:27 UTC (rev 200907)
@@ -1,4 +1,4 @@
-This test makes sure that calling the window scrolling methods with less than 2 arguments treats the missing arguments as 0.
+This tests calling the window scrolling with only 1 argument
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -9,9 +9,19 @@
Testing - scrollTo with 0 arguments
PASS window.scrollX is resetX
PASS window.scrollY is resetY
-Testing - scrollTo with 1 argument
-PASS window.scrollX is resetX + x
+PASS window.scrollX is x
+PASS window.scrollY is y
+Testing - scrollTo with 1 non-dictionary argument
+PASS scrollTo(0) threw exception TypeError: Type error.
+Testing - scrollTo with 1 dictionary argument
+PASS window.scrollX is x
PASS window.scrollY is resetY
+PASS window.scrollX is resetX
+PASS window.scrollY is y
+PASS window.scrollX is x
+PASS window.scrollY is y
+PASS window.scrollX is 0
+PASS window.scrollY is 0
Testing - scrollTo with more than 2 arguments
PASS window.scrollX is x
PASS window.scrollY is y
@@ -21,9 +31,19 @@
Testing - scroll with 0 arguments
PASS window.scrollX is resetX
PASS window.scrollY is resetY
-Testing - scroll with 1 argument
-PASS window.scrollX is resetX + x
+PASS window.scrollX is x
+PASS window.scrollY is y
+Testing - scroll with 1 non-dictionary argument
+PASS scroll(0) threw exception TypeError: Type error.
+Testing - scroll with 1 dictionary argument
+PASS window.scrollX is x
PASS window.scrollY is resetY
+PASS window.scrollX is resetX
+PASS window.scrollY is y
+PASS window.scrollX is x
+PASS window.scrollY is y
+PASS window.scrollX is 0
+PASS window.scrollY is 0
Testing - scroll with more than 2 arguments
PASS window.scrollX is x
PASS window.scrollY is y
@@ -33,9 +53,19 @@
Testing - scrollBy with 0 arguments
PASS window.scrollX is resetX
PASS window.scrollY is resetY
+PASS window.scrollX is x
+PASS window.scrollY is y
+Testing - scrollBy with 1 non-dictionary argument
+PASS scrollBy(0) threw exception TypeError: Type error.
Testing - scrollBy with 1 argument
PASS window.scrollX is resetX + x
PASS window.scrollY is resetY
+PASS window.scrollX is resetX
+PASS window.scrollY is resetY + y
+PASS window.scrollX is resetX + x
+PASS window.scrollY is resetY + y
+PASS window.scrollX is resetX + x
+PASS window.scrollY is resetY + y
Testing - scrollBy with more than 2 arguments
PASS window.scrollX is resetX + x
PASS window.scrollY is resetY + y
Modified: trunk/LayoutTests/fast/dom/Window/window-scroll-arguments.html (200906 => 200907)
--- trunk/LayoutTests/fast/dom/Window/window-scroll-arguments.html 2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/LayoutTests/fast/dom/Window/window-scroll-arguments.html 2016-05-14 02:10:27 UTC (rev 200907)
@@ -24,8 +24,7 @@
reset();
- description("This test makes sure that calling the window scrolling\
- methods with less than 2 arguments treats the missing arguments as 0.");
+ description("This tests calling the window scrolling with only 1 argument");
// scrollTo /////////////////////////
debug('');
@@ -37,12 +36,34 @@
shouldBe('window.scrollX', 'resetX');
shouldBe('window.scrollY', 'resetY');
reset();
+ window.scrollTo(x, y);
+ window.scrollTo();
+ shouldBe('window.scrollX', 'x');
+ shouldBe('window.scrollY', 'y');
+ reset();
- debug("Testing - scrollTo with 1 argument");
- window.scrollTo(x);
- shouldBe('window.scrollX', 'resetX + x');
+ debug("Testing - scrollTo with 1 non-dictionary argument");
+ shouldThrow("scrollTo(0)");
+ reset();
+
+ debug("Testing - scrollTo with 1 dictionary argument");
+ window.scrollTo({ left: x });
+ shouldBe('window.scrollX', 'x');
shouldBe('window.scrollY', 'resetY');
reset();
+ window.scrollTo({ top: y });
+ shouldBe('window.scrollX', 'resetX');
+ shouldBe('window.scrollY', 'y');
+ reset();
+ window.scrollTo({ left: x, top: y });
+ shouldBe('window.scrollX', 'x');
+ shouldBe('window.scrollY', 'y');
+ reset();
+ window.scrollTo(x, y);
+ window.scrollTo({ left: NaN, top: NaN });
+ shouldBe('window.scrollX', '0');
+ shouldBe('window.scrollY', '0');
+ reset();
debug("Testing - scrollTo with more than 2 arguments");
window.scrollTo(x, y, 200, "text");
@@ -60,12 +81,34 @@
shouldBe('window.scrollX', 'resetX');
shouldBe('window.scrollY', 'resetY');
reset();
+ window.scroll(x, y);
+ window.scroll();
+ shouldBe('window.scrollX', 'x');
+ shouldBe('window.scrollY', 'y');
+ reset();
- debug("Testing - scroll with 1 argument");
- window.scroll(x);
- shouldBe('window.scrollX', 'resetX + x');
+ debug("Testing - scroll with 1 non-dictionary argument");
+ shouldThrow("scroll(0)");
+ reset();
+
+ debug("Testing - scroll with 1 dictionary argument");
+ window.scroll({ left: x });
+ shouldBe('window.scrollX', 'x');
shouldBe('window.scrollY', 'resetY');
reset();
+ window.scroll({ top: y });
+ shouldBe('window.scrollX', 'resetX');
+ shouldBe('window.scrollY', 'y');
+ reset();
+ window.scroll({ left: x, top: y });
+ shouldBe('window.scrollX', 'x');
+ shouldBe('window.scrollY', 'y');
+ reset();
+ window.scroll(x, y);
+ window.scroll({ left: NaN, top: NaN });
+ shouldBe('window.scrollX', '0');
+ shouldBe('window.scrollY', '0');
+ reset();
debug("Testing - scroll with more than 2 arguments");
window.scroll(x, y, 200, "text");
@@ -83,12 +126,34 @@
shouldBe('window.scrollX', 'resetX');
shouldBe('window.scrollY', 'resetY');
reset();
+ window.scrollBy(x, y);
+ window.scrollBy();
+ shouldBe('window.scrollX', 'x');
+ shouldBe('window.scrollY', 'y');
+ reset();
+ debug("Testing - scrollBy with 1 non-dictionary argument");
+ shouldThrow("scrollBy(0)");
+ reset();
+
debug("Testing - scrollBy with 1 argument");
- window.scrollBy(x);
+ window.scrollBy({ left: x });
shouldBe('window.scrollX', 'resetX + x');
shouldBe('window.scrollY', 'resetY');
reset();
+ window.scrollBy({ top: y });
+ shouldBe('window.scrollX', 'resetX');
+ shouldBe('window.scrollY', 'resetY + y');
+ reset();
+ window.scrollBy({ left: x, top: y });
+ shouldBe('window.scrollX', 'resetX + x');
+ shouldBe('window.scrollY', 'resetY + y');
+ reset();
+ window.scrollBy(x, y);
+ window.scrollBy({ left: NaN, top: NaN });
+ shouldBe('window.scrollX', 'resetX + x');
+ shouldBe('window.scrollY', 'resetY + y');
+ reset();
debug("Testing - scrollBy with more than 2 arguments");
window.scrollBy(x, y, 200, "text");
Modified: trunk/LayoutTests/fast/dom/non-numeric-values-numeric-parameters-expected.txt (200906 => 200907)
--- trunk/LayoutTests/fast/dom/non-numeric-values-numeric-parameters-expected.txt 2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/LayoutTests/fast/dom/non-numeric-values-numeric-parameters-expected.txt 2016-05-14 02:10:27 UTC (rev 200907)
@@ -66,11 +66,11 @@
PASS nonNumericPolicy('document.createTreeWalker(document, x, null, false)') is 'any type allowed'
PASS nonNumericPolicy('document.createEvent("UIEvent").initUIEvent("a", false, false, null, x)') is 'any type allowed'
PASS nonNumericPolicy('window.scrollBy(x, 0)') is 'any type allowed'
-PASS nonNumericPolicy('window.scrollBy(0, x)') is 'any type allowed'
+PASS nonNumericPolicy('window.scrollBy(0, x)') is 'any type allowed (but not omitted)'
PASS nonNumericPolicy('window.scrollTo(x, 0)') is 'any type allowed'
-PASS nonNumericPolicy('window.scrollTo(0, x)') is 'any type allowed'
+PASS nonNumericPolicy('window.scrollTo(0, x)') is 'any type allowed (but not omitted)'
PASS nonNumericPolicy('window.scroll(x, 0)') is 'any type allowed'
-PASS nonNumericPolicy('window.scroll(0, x)') is 'any type allowed'
+PASS nonNumericPolicy('window.scroll(0, x)') is 'any type allowed (but not omitted)'
PASS nonNumericPolicy('window.moveBy(x, 0)') is 'any type allowed'
PASS nonNumericPolicy('window.moveBy(0, x)') is 'any type allowed'
PASS nonNumericPolicy('window.moveTo(x, 0)') is 'any type allowed'
Modified: trunk/LayoutTests/fast/dom/script-tests/non-numeric-values-numeric-parameters.js (200906 => 200907)
--- trunk/LayoutTests/fast/dom/script-tests/non-numeric-values-numeric-parameters.js 2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/LayoutTests/fast/dom/script-tests/non-numeric-values-numeric-parameters.js 2016-05-14 02:10:27 UTC (rev 200907)
@@ -344,11 +344,11 @@
// Window
shouldBe("nonNumericPolicy('window.scrollBy(x, 0)')", "'any type allowed'");
-shouldBe("nonNumericPolicy('window.scrollBy(0, x)')", "'any type allowed'");
+shouldBe("nonNumericPolicy('window.scrollBy(0, x)')", "'any type allowed (but not omitted)'");
shouldBe("nonNumericPolicy('window.scrollTo(x, 0)')", "'any type allowed'");
-shouldBe("nonNumericPolicy('window.scrollTo(0, x)')", "'any type allowed'");
+shouldBe("nonNumericPolicy('window.scrollTo(0, x)')", "'any type allowed (but not omitted)'");
shouldBe("nonNumericPolicy('window.scroll(x, 0)')", "'any type allowed'");
-shouldBe("nonNumericPolicy('window.scroll(0, x)')", "'any type allowed'");
+shouldBe("nonNumericPolicy('window.scroll(0, x)')", "'any type allowed (but not omitted)'");
shouldBe("nonNumericPolicy('window.moveBy(x, 0)')", "'any type allowed'");
shouldBe("nonNumericPolicy('window.moveBy(0, x)')", "'any type allowed'");
shouldBe("nonNumericPolicy('window.moveTo(x, 0)')", "'any type allowed'");
Modified: trunk/Source/WebCore/ChangeLog (200906 => 200907)
--- trunk/Source/WebCore/ChangeLog 2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/ChangeLog 2016-05-14 02:10:27 UTC (rev 200907)
@@ -1,3 +1,55 @@
+2016-05-13 Chris Dumez <[email protected]>
+
+ Align window.scroll() / scrollTo() / scrollBy() with the CSSOM specification
+ https://bugs.webkit.org/show_bug.cgi?id=157666
+
+ Reviewed by Darin Adler.
+
+ Align window.scroll() / scrollTo() / scrollBy() with Firefox and the CSSOM
+ specification:
+ https://drafts.csswg.org/cssom-view/#extensions-to-the-window-interface
+
+ In particular, the following changes were made:
+ 1. Make parameters to scroll() / scrollTo() / scrollBy() mandatory.
+ 2. Add overloads for scroll() / scrollTo() / scrollBy() that take an
+ optional ScrollToOptions dictionary.
+ 3. Update API to use "unrestricted double" typing for x/y instead of
+ "long". This matches the specification but it does not really change
+ our behavior at this point because the values are still casted to
+ int in our implementation.
+
+ Web-Exposed behavior changes:
+ 1. JS can now pass a dictionary to scroll() / scrollTo() / scrollBy().
+ This a new feature that Firefox already supports (Chrome does not).
+ 2. Passing only 1 parameter to scroll() / scrollTo() / scrollBy() that
+ is not a dictionary will now throw a TypeError. The compatibility
+ risky should be low because Firefox and Chrome already throw in this
+ case (Chrome has been throwing for 2 years and a half).
+ 3. Calling scrollTo() / scroll() without any parameter no longer
+ scrolls to 0. Instead we use the current viewport's x/y which means
+ we don't scroll at all. The new behavior matches Firefox, Chrome and
+ IE 11. This fixes scrolling on the following Website:
+ https://members.chosun.com/cms_subscribe/application/index.jsp
+
+ No new tests, extended existing testing.
+
+ * bindings/js/JSDOMConvert.h:
+ (WebCore::convert):
+ (WebCore::convertOptional):
+ * bindings/scripts/CodeGeneratorJS.pm:
+ (ShouldAllowNonFiniteForFloatingPointType):
+ (GenerateConversionRuleWithLeadingComma):
+ (GenerateDictionaryImplementationContent):
+ (JSValueToNative):
+ * bindings/scripts/test/JS/JSTestObj.cpp:
+ (WebCore::convert<TestObj::Dictionary>):
+ * bindings/scripts/test/TestObj.idl:
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::scrollBy):
+ (WebCore::DOMWindow::scrollTo):
+ * page/DOMWindow.h:
+ * page/DOMWindow.idl:
+
2016-05-13 Commit Queue <[email protected]>
Unreviewed, rolling out r200894.
Modified: trunk/Source/WebCore/bindings/js/JSDOMConvert.h (200906 => 200907)
--- trunk/Source/WebCore/bindings/js/JSDOMConvert.h 2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvert.h 2016-05-14 02:10:27 UTC (rev 200907)
@@ -32,7 +32,7 @@
enum class ShouldAllowNonFinite { No, Yes };
-template<typename T> struct Converter;
+template<typename T, typename Enable = void> struct Converter;
template<typename T> T convert(JSC::ExecState&, JSC::JSValue);
template<typename T> T convert(JSC::ExecState&, JSC::JSValue, IntegerConversionConfiguration);
@@ -41,6 +41,9 @@
template<typename T> typename Converter<T>::OptionalValue convertOptional(JSC::ExecState&, JSC::JSValue);
template<typename T, typename U> T convertOptional(JSC::ExecState&, JSC::JSValue, U&& defaultValue);
+template<typename T> typename Converter<T>::OptionalValue convertOptional(JSC::ExecState&, JSC::JSValue, ShouldAllowNonFinite);
+template<typename T, typename U> T convertOptional(JSC::ExecState&, JSC::JSValue, ShouldAllowNonFinite, U&& defaultValue);
+
// This is where the implementation of the things declared above begins:
template<typename T> T convert(JSC::ExecState& state, JSC::JSValue value)
@@ -56,10 +59,7 @@
template<typename T> inline T convert(JSC::ExecState& state, JSC::JSValue value, ShouldAllowNonFinite allow)
{
static_assert(std::is_same<T, float>::value || std::is_same<T, double>::value, "ShouldAllowNonFinite can only be used with float or double");
- double number = value.toNumber(&state);
- if (allow == ShouldAllowNonFinite::No && UNLIKELY(!std::isfinite(number)))
- throwNonFiniteTypeError(state);
- return static_cast<T>(number);
+ return Converter<T>::convert(state, value, allow);
}
template<typename T> typename Converter<T>::OptionalValue inline convertOptional(JSC::ExecState& state, JSC::JSValue value)
@@ -72,11 +72,21 @@
return value.isUndefined() ? std::forward<U>(defaultValue) : convert<T>(state, value);
}
+template<typename T> typename Converter<T>::OptionalValue inline convertOptional(JSC::ExecState& state, JSC::JSValue value, ShouldAllowNonFinite allow)
+{
+ return value.isUndefined() ? typename Converter<T>::OptionalValue() : convert<T>(state, value, allow);
+}
+
+template<typename T, typename U> inline T convertOptional(JSC::ExecState& state, JSC::JSValue value, ShouldAllowNonFinite allow, U&& defaultValue)
+{
+ return value.isUndefined() ? std::forward<U>(defaultValue) : convert<T>(state, value, allow);
+}
+
template<typename T> struct DefaultConverter {
using OptionalValue = Optional<T>;
};
-template<typename T> struct Converter : DefaultConverter<T> {
+template<typename T, typename Enable> struct Converter : DefaultConverter<T> {
};
template<> struct Converter<bool> : DefaultConverter<bool> {
@@ -228,4 +238,14 @@
}
};
+template<typename T> struct Converter<T, typename std::enable_if<std::is_floating_point<T>::value>::type> : DefaultConverter<T> {
+ static T convert(JSC::ExecState& state, JSC::JSValue value, ShouldAllowNonFinite allow)
+ {
+ double number = value.toNumber(&state);
+ if (allow == ShouldAllowNonFinite::No && UNLIKELY(!std::isfinite(number)))
+ throwNonFiniteTypeError(state);
+ return static_cast<T>(number);
+ }
+};
+
} // namespace WebCore
Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (200906 => 200907)
--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2016-05-14 02:10:27 UTC (rev 200907)
@@ -958,6 +958,25 @@
return $value;
}
+sub ShouldAllowNonFiniteForFloatingPointType
+{
+ my $type = shift;
+
+ die "Can only be called with floating point types" unless $codeGenerator->IsFloatingPointType($type);
+ return $type eq "unrestricted double" || $type eq "unrestricted float";
+}
+
+sub GenerateConversionRuleWithLeadingComma
+{
+ my ($interface, $member) = @_;
+
+ if ($codeGenerator->IsFloatingPointType($member->type)) {
+ return ", " . (ShouldAllowNonFiniteForFloatingPointType($member->type) ? "ShouldAllowNonFinite::Yes" : "ShouldAllowNonFinite::No");
+ }
+ # FIXME: Add support for integer types.
+ return "";
+}
+
sub GenerateDefaultValueWithLeadingComma
{
my ($interface, $member) = @_;
@@ -1011,9 +1030,9 @@
}
# FIXME: Eventually we will want this to share a lot more code with JSValueToNative.
my $function = $member->isOptional ? "convertOptional" : "convert";
- my $defaultValueWithLeadingComma = $member->isOptional && defined $member->default ? ", " . $member->default : "";
$result .= " auto " . $member->name . " = " . $function . "<" . GetNativeTypeFromSignature($interface, $member) . ">"
. "(state, object->get(&state, Identifier::fromString(&state, \"" . $member->name . "\"))"
+ . GenerateConversionRuleWithLeadingComma($interface, $member)
. GenerateDefaultValueWithLeadingComma($interface, $member) . ");\n";
$needExceptionCheck = 1;
}
@@ -4425,11 +4444,9 @@
if ($codeGenerator->IsFloatingPointType($type)) {
AddToImplIncludes("JSDOMConvert.h");
- return ("convert<double>(*state, $value, ShouldAllowNonFinite::No)", 1) if $type eq "double";
- return ("convert<double>(*state, $value, ShouldAllowNonFinite::Yes)", 1) if $type eq "unrestricted double";
- return ("convert<float>(*state, $value, ShouldAllowNonFinite::No)", 1) if $type eq "float";
- return ("convert<float>(*state, $value, ShouldAllowNonFinite::Yes)", 1) if $type eq "unrestricted float";
- die "Unhandled floating point type: " . $type;
+ my $allowNonFinite = ShouldAllowNonFiniteForFloatingPointType($type) ? "ShouldAllowNonFinite::Yes" : "ShouldAllowNonFinite::No";
+ my $nativeType = GetNativeType($interface, $type);
+ return ("convert<$nativeType>(*state, $value, $allowNonFinite)", 1);
}
return ("valueToDate(state, $value)", 1) if $type eq "Date";
Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (200906 => 200907)
--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp 2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp 2016-05-14 02:10:27 UTC (rev 200907)
@@ -455,7 +455,7 @@
template<> TestObj::Dictionary convert<TestObj::Dictionary>(ExecState& state, JSValue value)
{
if (value.isUndefinedOrNull())
- return { { }, TestObj::EnumType::EnumValue1, TestObj::EnumType::EmptyString, "defaultString", { }, false, { }, { } };
+ return { { }, TestObj::EnumType::EnumValue1, TestObj::EnumType::EmptyString, "defaultString", { }, false, { }, { }, { }, { }, 0, 0, { }, { }, 0, 0 };
auto* object = value.getObject();
if (UNLIKELY(!object || object->type() == RegExpObjectType)) {
throwTypeError(&state);
@@ -483,7 +483,31 @@
if (UNLIKELY(state.hadException()))
return { };
auto sequenceOfStrings = convertOptional<Vector<String>>(state, object->get(&state, Identifier::fromString(&state, "sequenceOfStrings")));
- return { WTFMove(enumerationValueWithoutDefault), WTFMove(enumerationValueWithDefault), WTFMove(enumerationValueWithEmptyStringDefault), WTFMove(stringWithDefault), WTFMove(stringWithoutDefault), WTFMove(booleanWithDefault), WTFMove(booleanWithoutDefault), WTFMove(sequenceOfStrings) };
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto restrictedDouble = convertOptional<double>(state, object->get(&state, Identifier::fromString(&state, "restrictedDouble")), ShouldAllowNonFinite::No);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto unrestrictedDouble = convertOptional<double>(state, object->get(&state, Identifier::fromString(&state, "unrestrictedDouble")), ShouldAllowNonFinite::Yes);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto restrictedDoubleWithDefault = convertOptional<double>(state, object->get(&state, Identifier::fromString(&state, "restrictedDoubleWithDefault")), ShouldAllowNonFinite::No, 0);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto unrestrictedDoubleWithDefault = convertOptional<double>(state, object->get(&state, Identifier::fromString(&state, "unrestrictedDoubleWithDefault")), ShouldAllowNonFinite::Yes, 0);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto restrictedFloat = convertOptional<float>(state, object->get(&state, Identifier::fromString(&state, "restrictedFloat")), ShouldAllowNonFinite::No);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto unrestrictedFloat = convertOptional<float>(state, object->get(&state, Identifier::fromString(&state, "unrestrictedFloat")), ShouldAllowNonFinite::Yes);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto restrictedFloatWithDefault = convertOptional<float>(state, object->get(&state, Identifier::fromString(&state, "restrictedFloatWithDefault")), ShouldAllowNonFinite::No, 0);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto unrestrictedFloatWithDefault = convertOptional<float>(state, object->get(&state, Identifier::fromString(&state, "unrestrictedFloatWithDefault")), ShouldAllowNonFinite::Yes, 0);
+ return { WTFMove(enumerationValueWithoutDefault), WTFMove(enumerationValueWithDefault), WTFMove(enumerationValueWithEmptyStringDefault), WTFMove(stringWithDefault), WTFMove(stringWithoutDefault), WTFMove(booleanWithDefault), WTFMove(booleanWithoutDefault), WTFMove(sequenceOfStrings), WTFMove(restrictedDouble), WTFMove(unrestrictedDouble), WTFMove(restrictedDoubleWithDefault), WTFMove(unrestrictedDoubleWithDefault), WTFMove(restrictedFloat), WTFMove(unrestrictedFloat), WTFMove(restrictedFloatWithDefault), WTFMove(unrestrictedFloatWithDefault) };
}
template<> TestObj::DictionaryThatShouldNotTolerateNull convert<TestObj::DictionaryThatShouldNotTolerateNull>(ExecState& state, JSValue value)
Modified: trunk/Source/WebCore/bindings/scripts/test/TestObj.idl (200906 => 200907)
--- trunk/Source/WebCore/bindings/scripts/test/TestObj.idl 2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/bindings/scripts/test/TestObj.idl 2016-05-14 02:10:27 UTC (rev 200907)
@@ -391,6 +391,14 @@
boolean booleanWithDefault = false;
boolean booleanWithoutDefault;
sequence<DOMString> sequenceOfStrings;
+ double restrictedDouble;
+ unrestricted double unrestrictedDouble;
+ double restrictedDoubleWithDefault = 0;
+ unrestricted double unrestrictedDoubleWithDefault = 0;
+ float restrictedFloat;
+ unrestricted float unrestrictedFloat;
+ float restrictedFloatWithDefault = 0;
+ unrestricted float unrestrictedFloatWithDefault = 0;
};
dictionary TestDictionaryThatShouldNotTolerateNull {
Modified: trunk/Source/WebCore/page/DOMWindow.cpp (200906 => 200907)
--- trunk/Source/WebCore/page/DOMWindow.cpp 2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/page/DOMWindow.cpp 2016-05-14 02:10:27 UTC (rev 200907)
@@ -1493,8 +1493,13 @@
return page->deviceScaleFactor();
}
-void DOMWindow::scrollBy(int x, int y) const
+void DOMWindow::scrollBy(const ScrollToOptions& options) const
{
+ return scrollBy(options.left.valueOr(0), options.top.valueOr(0));
+}
+
+void DOMWindow::scrollBy(double x, double y) const
+{
if (!isCurrentlyDisplayedInFrame())
return;
@@ -1504,12 +1509,27 @@
if (!view)
return;
+ // Normalize non-finite values (https://drafts.csswg.org/cssom-view/#normalize-non-finite-values).
+ x = std::isfinite(x) ? x : 0;
+ y = std::isfinite(y) ? y : 0;
+
IntSize scaledOffset(view->mapFromCSSToLayoutUnits(x), view->mapFromCSSToLayoutUnits(y));
view->setContentsScrollPosition(view->contentsScrollPosition() + scaledOffset);
}
-void DOMWindow::scrollTo(int x, int y) const
+void DOMWindow::scrollTo(const ScrollToOptions& options) const
{
+ RefPtr<FrameView> view = m_frame->view();
+ if (!view)
+ return;
+
+ double x = options.left ? options.left.value() : view->contentsScrollPosition().x();
+ double y = options.top ? options.top.value() : view->contentsScrollPosition().y();
+ return scrollTo(x, y);
+}
+
+void DOMWindow::scrollTo(double x, double y) const
+{
if (!isCurrentlyDisplayedInFrame())
return;
@@ -1517,6 +1537,10 @@
if (!view)
return;
+ // Normalize non-finite values (https://drafts.csswg.org/cssom-view/#normalize-non-finite-values).
+ x = std::isfinite(x) ? x : 0;
+ y = std::isfinite(y) ? y : 0;
+
if (!x && !y && view->contentsScrollPosition() == IntPoint(0, 0))
return;
Modified: trunk/Source/WebCore/page/DOMWindow.h (200906 => 200907)
--- trunk/Source/WebCore/page/DOMWindow.h 2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/page/DOMWindow.h 2016-05-14 02:10:27 UTC (rev 200907)
@@ -248,10 +248,16 @@
void postMessageTimerFired(PostMessageTimer&);
void dispatchMessageEventWithOriginCheck(SecurityOrigin* intendedTargetOrigin, Event&, PassRefPtr<Inspector::ScriptCallStack>);
- void scrollBy(int x, int y) const;
- void scrollTo(int x, int y) const;
- void scroll(int x, int y) const { scrollTo(x, y); }
+ struct ScrollToOptions {
+ Optional<double> left;
+ Optional<double> top;
+ };
+ void scrollBy(const ScrollToOptions&) const;
+ void scrollBy(double x, double y) const;
+ void scrollTo(const ScrollToOptions&) const;
+ void scrollTo(double x, double y) const;
+
void moveBy(float x, float y) const;
void moveTo(float x, float y) const;
Modified: trunk/Source/WebCore/page/DOMWindow.idl (200906 => 200907)
--- trunk/Source/WebCore/page/DOMWindow.idl 2016-05-14 02:03:10 UTC (rev 200906)
+++ trunk/Source/WebCore/page/DOMWindow.idl 2016-05-14 02:10:27 UTC (rev 200907)
@@ -102,9 +102,16 @@
readonly attribute long pageXOffset;
readonly attribute long pageYOffset;
- void scrollBy(optional long x = 0, optional long y = 0);
- void scrollTo(optional long x = 0, optional long y = 0);
- void scroll(optional long x = 0, optional long y = 0);
+ void scrollBy(unrestricted double x, unrestricted double y);
+ void scrollTo(unrestricted double x, unrestricted double y);
+ [ImplementedAs=scrollTo] void scroll(unrestricted double x, unrestricted double y);
+
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ void scrollBy(optional ScrollToOptions option);
+ void scrollTo(optional ScrollToOptions options);
+ [ImplementedAs=scrollTo] void scroll(optional ScrollToOptions options);
+#endif
+
void moveBy(optional unrestricted float x = NaN, optional unrestricted float y = NaN); // FIXME: this should take longs not floats.
void moveTo(optional unrestricted float x = NaN, optional unrestricted float y = NaN); // FIXME: this should take longs not floats.
void resizeBy(optional unrestricted float x = NaN, optional unrestricted float y = NaN); // FIXME: this should take longs not floats.
@@ -217,6 +224,12 @@
[NotEnumerable, Conditional=PROXIMITY_EVENTS] attribute EventHandler onwebkitdeviceproximity;
};
+// FIXME: Support ScrollBehavior.
+dictionary ScrollToOptions {
+ unrestricted double left;
+ unrestricted double top;
+};
+
DOMWindow implements GlobalEventHandlers;
DOMWindow implements WindowBase64;
DOMWindow implements WindowEventHandlers;