Bug 1419221 - Introduce a new argument for getUnanimatedComputedStyle to be able to flush pending styles. r=birtles

Even with this patch, in Gecko getUnanimatedComputedStyle flushes pendings
styles somehow.  Also in Stylo the function flushes pending styles if the
target element hasn't yet styled or Servo style data has cleared for some
reasons (e.g. the element is in display:none subtree).

MozReview-Commit-ID: HCizzM0JnFz
This commit is contained in:
Hiroyuki Ikezoe
2017-11-21 18:03:17 +09:00
parent 72a4e1a44e
commit 4ee9c6ff0c
4 changed files with 54 additions and 7 deletions

View File

@@ -509,7 +509,10 @@ var AnimationPlayerActor = protocol.ActorClassWithSpec(animationPlayerSpec, {
target = target.parentElement; target = target.parentElement;
} }
const value = const value =
DOMWindowUtils.getUnanimatedComputedStyle(target, pseudo, property.name); DOMWindowUtils.getUnanimatedComputedStyle(target,
pseudo,
property.name,
DOMWindowUtils.FLUSH_NONE);
const animationType = DOMWindowUtils.getAnimationTypeForLonghand(property.name); const animationType = DOMWindowUtils.getAnimationTypeForLonghand(property.name);
underlyingValue = animationType === "float" ? parseFloat(value, 10) : value; underlyingValue = animationType === "float" ? parseFloat(value, 10) : value;
} }

View File

@@ -2970,6 +2970,7 @@ NS_IMETHODIMP
nsDOMWindowUtils::GetUnanimatedComputedStyle(nsIDOMElement* aElement, nsDOMWindowUtils::GetUnanimatedComputedStyle(nsIDOMElement* aElement,
const nsAString& aPseudoElement, const nsAString& aPseudoElement,
const nsAString& aProperty, const nsAString& aProperty,
int32_t aFlushType,
nsAString& aResult) nsAString& aResult)
{ {
nsCOMPtr<Element> element = do_QueryInterface(aElement); nsCOMPtr<Element> element = do_QueryInterface(aElement);
@@ -2984,6 +2985,20 @@ nsDOMWindowUtils::GetUnanimatedComputedStyle(nsIDOMElement* aElement,
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
} }
switch (aFlushType) {
case FLUSH_NONE:
break;
case FLUSH_STYLE: {
nsIDocument* doc = element->GetComposedDoc();
if (doc) {
doc->FlushPendingNotifications(FlushType::Style);
}
break;
}
default:
return NS_ERROR_INVALID_ARG;
}
nsIPresShell* shell = GetPresShell(); nsIPresShell* shell = GetPresShell();
if (!shell) { if (!shell) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;

View File

@@ -102,20 +102,45 @@ function test_getUnanimatedComputedStyle() {
document.body.appendChild(div); document.body.appendChild(div);
SimpleTest.doesThrow( SimpleTest.doesThrow(
() => utils.getUnanimatedComputedStyle(div, null, "background"), () => utils.getUnanimatedComputedStyle(div, null, "background", utils.FLUSH_NONE),
"NS_ERROR_INVALID_ARG", "NS_ERROR_INVALID_ARG",
"Shorthand property should throw"); "Shorthand property should throw");
SimpleTest.doesThrow( SimpleTest.doesThrow(
() => utils.getUnanimatedComputedStyle(div, null, "invalid"), () => utils.getUnanimatedComputedStyle(div, null, "invalid", utils.FLUSH_NONE),
"NS_ERROR_INVALID_ARG", "NS_ERROR_INVALID_ARG",
"Invalid property should throw"); "Invalid property should throw");
SimpleTest.doesThrow( SimpleTest.doesThrow(
() => utils.getUnanimatedComputedStyle(null, null, "opacity"), () => utils.getUnanimatedComputedStyle(null, null, "opacity", utils.FLUSH_NONE),
"NS_ERROR_INVALID_ARG", "NS_ERROR_INVALID_ARG",
"Null element should throw"); "Null element should throw");
SimpleTest.doesThrow(
() => utils.getUnanimatedComputedStyle(div, null, "opacity", utils.FLUSH_LAYOUT),
"NS_ERROR_INVALID_ARG",
"FLUSH_LAYOUT option should throw");
SimpleTest.doesThrow(
() => utils.getUnanimatedComputedStyle(div, null, "opacity", utils.FLUSH_DISPLAY),
"NS_ERROR_INVALID_ARG",
"FLUSH_DISPLAY option should throw");
if (utils.isStyledByServo) {
// Flush styles since getUnanimatedComputedStyle flushes pending styles even
// with FLUSH_NONE option if the element hasn't yet styled.
getComputedStyle(div).opacity;
div.style.opacity = "0";
is(utils.getUnanimatedComputedStyle(div, null, "opacity", utils.FLUSH_NONE),
"1",
"getUnanimatedComputedStyle with FLUSH_NONE should not flush pending styles");
is(utils.getUnanimatedComputedStyle(div, null, "opacity", utils.FLUSH_STYLE),
"0",
"getUnanimatedComputedStyle with FLUSH_STYLE should flush pending styles");
}
div.remove(); div.remove();
next(); next();
@@ -136,7 +161,7 @@ function checkUnanimatedComputedStyle(property, initialStyle, pseudoType,
div.classList.add("pseudo"); div.classList.add("pseudo");
} }
is(utils.getUnanimatedComputedStyle(div, pseudoType, property), is(utils.getUnanimatedComputedStyle(div, pseudoType, property, utils.FLUSH_STYLE),
expectedBeforeAnimation, expectedBeforeAnimation,
`'${ property }' property with '${ initialStyle }' style ` `'${ property }' property with '${ initialStyle }' style `
+ `should be '${ expectedBeforeAnimation }' ` + `should be '${ expectedBeforeAnimation }' `
@@ -144,7 +169,7 @@ function checkUnanimatedComputedStyle(property, initialStyle, pseudoType,
const animation = animate(div); const animation = animate(div);
animation.currentTime = 500; animation.currentTime = 500;
is(utils.getUnanimatedComputedStyle(div, pseudoType, property), is(utils.getUnanimatedComputedStyle(div, pseudoType, property, utils.FLUSH_STYLE),
expectedDuringAnimation, expectedDuringAnimation,
`'${ property }' property with '${ initialStyle }' style ` `'${ property }' property with '${ initialStyle }' style `
+ `should be '${ expectedDuringAnimation }' ` + `should be '${ expectedDuringAnimation }' `

View File

@@ -990,6 +990,7 @@ interface nsIDOMWindowUtils : nsISupports {
*/ */
nsIDOMClientRect getBoundsWithoutFlushing(in nsIDOMElement aElement); nsIDOMClientRect getBoundsWithoutFlushing(in nsIDOMElement aElement);
const long FLUSH_NONE = -1;
const long FLUSH_STYLE = 0; const long FLUSH_STYLE = 0;
const long FLUSH_LAYOUT = 1; const long FLUSH_LAYOUT = 1;
const long FLUSH_DISPLAY = 2; const long FLUSH_DISPLAY = 2;
@@ -1581,10 +1582,13 @@ interface nsIDOMWindowUtils : nsISupports {
* @param aElement - A target element * @param aElement - A target element
* @param aPseudoElement - A pseudo type (e.g. '::before' or null) * @param aPseudoElement - A pseudo type (e.g. '::before' or null)
* @param aProperty - A longhand CSS property (e.g. 'background-color') * @param aProperty - A longhand CSS property (e.g. 'background-color')
* @param aFlushType - FLUSH_NONE if any pending styles should not happen,
* FLUSH_STYLE to flush pending styles.
*/ */
AString getUnanimatedComputedStyle(in nsIDOMElement aElement, AString getUnanimatedComputedStyle(in nsIDOMElement aElement,
in AString aPseudoElement, in AString aPseudoElement,
in AString aProperty); in AString aProperty,
in long aFlushType);
/** /**
* Get the type of the currently focused html input, if any. * Get the type of the currently focused html input, if any.