Flush layout earlier in getComputedStyle(). (Bug 454276) r+sr=bzbarsky

This commit is contained in:
L. David Baron 2009-02-24 16:14:45 -08:00
Родитель bb4f9f42dd
Коммит bc6a61c62b
2 изменённых файлов: 86 добавлений и 78 удалений

Просмотреть файл

@ -318,11 +318,38 @@ nsComputedDOMStyle::GetPropertyCSSValue(const nsAString& aPropertyName,
nsCOMPtr<nsIDocument> document = do_QueryReferent(mDocumentWeak);
NS_ENSURE_TRUE(document, NS_ERROR_NOT_AVAILABLE);
nsCSSProperty prop = nsCSSProps::LookupProperty(aPropertyName);
const ComputedStyleMapEntry* propEntry = nsnull;
{
PRUint32 length = 0;
const ComputedStyleMapEntry* propMap = GetQueryablePropertyMap(&length);
for (PRUint32 i = 0; i < length; ++i) {
if (prop == propMap[i].mProperty) {
propEntry = &propMap[i];
break;
}
}
}
if (!propEntry) {
#ifdef DEBUG_ComputedDOMStyle
NS_WARNING(PromiseFlatCString(NS_ConvertUTF16toUTF8(aPropertyName) +
NS_LITERAL_CSTRING(" is not queryable!")).get());
#endif
// NOTE: For branches, we should flush here for compatibility!
return NS_OK;
}
// Flush _before_ getting the presshell, since that could create a new
// presshell. Also note that we want to flush the style on the document
// we're computing style in, not on the document mContent is in -- the two
// may be different.
document->FlushPendingNotifications(Flush_Style);
document->FlushPendingNotifications(
propEntry->mNeedsLayoutFlush ? Flush_Layout : Flush_Style);
#ifdef DEBUG
mFlushedPendingReflows = propEntry->mNeedsLayoutFlush;
#endif
mPresShell = document->GetPrimaryShell();
NS_ENSURE_TRUE(mPresShell && mPresShell->GetPresContext(),
@ -353,27 +380,8 @@ nsComputedDOMStyle::GetPropertyCSSValue(const nsAString& aPropertyName,
NS_ASSERTION(mStyleContextHolder, "Frame without style context?");
}
nsresult rv = NS_OK;
nsCSSProperty prop = nsCSSProps::LookupProperty(aPropertyName);
PRUint32 i = 0;
PRUint32 length = 0;
const ComputedStyleMapEntry* propMap = GetQueryablePropertyMap(&length);
for (; i < length; ++i) {
if (prop == propMap[i].mProperty) {
// Call our pointer-to-member-function.
rv = (this->*(propMap[i].mGetter))(aReturn);
break;
}
}
#ifdef DEBUG_ComputedDOMStyle
if (i == length) {
NS_WARNING(PromiseFlatCString(NS_ConvertUTF16toUTF8(aPropertyName) +
NS_LITERAL_CSTRING(" is not queryable!")).get());
}
#endif
// Call our pointer-to-member-function.
nsresult rv = (this->*(propEntry->mGetter))(aReturn);
if (NS_FAILED(rv)) {
*aReturn = nsnull;
@ -2898,7 +2906,7 @@ nsComputedDOMStyle::GetHeight(nsIDOMCSSValue** aValue)
}
if (calcHeight) {
FlushPendingReflows();
AssertFlushedPendingReflows();
val->SetAppUnits(mInnerFrame->GetContentRect().height);
} else {
@ -2939,7 +2947,7 @@ nsComputedDOMStyle::GetWidth(nsIDOMCSSValue** aValue)
}
if (calcWidth) {
FlushPendingReflows();
AssertFlushedPendingReflows();
val->SetAppUnits(mInnerFrame->GetContentRect().width);
} else {
@ -3054,7 +3062,7 @@ nsComputedDOMStyle::GetOffsetWidthFor(PRUint8 aSide, nsIDOMCSSValue** aValue)
{
const nsStyleDisplay* display = GetStyleDisplay();
FlushPendingReflows();
AssertFlushedPendingReflows();
nsresult rv = NS_OK;
switch (display->mPosition) {
@ -3187,16 +3195,6 @@ nsComputedDOMStyle::GetStaticOffset(PRUint8 aSide, nsIDOMCSSValue** aValue)
return CallQueryInterface(val, aValue);
}
void
nsComputedDOMStyle::FlushPendingReflows()
{
// Flush all pending notifications so that our frames are up to date
nsCOMPtr<nsIDocument> document = mContent->GetDocument();
if (document) {
document->FlushPendingNotifications(Flush_Layout);
}
}
nsresult
nsComputedDOMStyle::GetPaddingWidthFor(PRUint8 aSide, nsIDOMCSSValue** aValue)
{
@ -3206,7 +3204,7 @@ nsComputedDOMStyle::GetPaddingWidthFor(PRUint8 aSide, nsIDOMCSSValue** aValue)
if (!mInnerFrame) {
SetValueToCoord(val, GetStylePadding()->mPadding.Get(aSide));
} else {
FlushPendingReflows();
AssertFlushedPendingReflows();
val->SetAppUnits(mInnerFrame->GetUsedPadding().side(aSide));
}
@ -3285,7 +3283,7 @@ nsComputedDOMStyle::GetBorderWidthFor(PRUint8 aSide, nsIDOMCSSValue** aValue)
nscoord width;
if (mInnerFrame) {
FlushPendingReflows();
AssertFlushedPendingReflows();
width = mInnerFrame->GetUsedBorder().side(aSide);
} else {
width = GetStyleBorder()->GetActualBorderWidth(aSide);
@ -3326,7 +3324,7 @@ nsComputedDOMStyle::GetMarginWidthFor(PRUint8 aSide, nsIDOMCSSValue** aValue)
if (!mInnerFrame) {
SetValueToCoord(val, GetStyleMargin()->mMargin.Get(aSide));
} else {
FlushPendingReflows();
AssertFlushedPendingReflows();
val->SetAppUnits(mInnerFrame->GetUsedMargin().side(aSide));
}
@ -3451,7 +3449,7 @@ nsComputedDOMStyle::GetCBContentWidth(nscoord& aWidth)
return PR_FALSE;
}
FlushPendingReflows();
AssertFlushedPendingReflows();
aWidth = container->GetContentRect().width;
return PR_TRUE;
@ -3469,7 +3467,7 @@ nsComputedDOMStyle::GetCBContentHeight(nscoord& aHeight)
return PR_FALSE;
}
FlushPendingReflows();
AssertFlushedPendingReflows();
aHeight = container->GetContentRect().height;
return PR_TRUE;
@ -3482,7 +3480,7 @@ nsComputedDOMStyle::GetFrameBorderRectWidth(nscoord& aWidth)
return PR_FALSE;
}
FlushPendingReflows();
AssertFlushedPendingReflows();
aWidth = mInnerFrame->GetSize().width;
return PR_TRUE;
@ -3496,7 +3494,7 @@ nsComputedDOMStyle::GetFrameBoundsWidthForTransform(nscoord& aWidth)
return PR_FALSE;
}
FlushPendingReflows();
AssertFlushedPendingReflows();
// Check to see that we're transformed.
if (!mInnerFrame->GetStyleDisplay()->HasTransform())
@ -3514,7 +3512,7 @@ nsComputedDOMStyle::GetFrameBoundsHeightForTransform(nscoord& aHeight)
return PR_FALSE;
}
FlushPendingReflows();
AssertFlushedPendingReflows();
// Check to see that we're transformed.
if (!mInnerFrame->GetStyleDisplay()->HasTransform())
@ -4028,7 +4026,9 @@ nsComputedDOMStyle::GetMask(nsIDOMCSSValue** aValue)
#define COMPUTED_STYLE_MAP_ENTRY(_prop, _method) \
{ eCSSProperty_##_prop, &nsComputedDOMStyle::Get##_method }
{ eCSSProperty_##_prop, &nsComputedDOMStyle::Get##_method, PR_FALSE }
#define COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_prop, _method) \
{ eCSSProperty_##_prop, &nsComputedDOMStyle::Get##_method, PR_TRUE }
const nsComputedDOMStyle::ComputedStyleMapEntry*
nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
@ -4062,25 +4062,25 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
//// COMPUTED_STYLE_MAP_ENTRY(border_bottom, BorderBottom),
COMPUTED_STYLE_MAP_ENTRY(border_bottom_color, BorderBottomColor),
COMPUTED_STYLE_MAP_ENTRY(border_bottom_style, BorderBottomStyle),
COMPUTED_STYLE_MAP_ENTRY(border_bottom_width, BorderBottomWidth),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(border_bottom_width, BorderBottomWidth),
COMPUTED_STYLE_MAP_ENTRY(border_collapse, BorderCollapse),
//// COMPUTED_STYLE_MAP_ENTRY(border_color, BorderColor),
//// COMPUTED_STYLE_MAP_ENTRY(border_left, BorderLeft),
COMPUTED_STYLE_MAP_ENTRY(border_left_color, BorderLeftColor),
COMPUTED_STYLE_MAP_ENTRY(border_left_style, BorderLeftStyle),
COMPUTED_STYLE_MAP_ENTRY(border_left_width, BorderLeftWidth),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(border_left_width, BorderLeftWidth),
//// COMPUTED_STYLE_MAP_ENTRY(border_right, BorderRight),
COMPUTED_STYLE_MAP_ENTRY(border_right_color, BorderRightColor),
COMPUTED_STYLE_MAP_ENTRY(border_right_style, BorderRightStyle),
COMPUTED_STYLE_MAP_ENTRY(border_right_width, BorderRightWidth),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(border_right_width, BorderRightWidth),
COMPUTED_STYLE_MAP_ENTRY(border_spacing, BorderSpacing),
//// COMPUTED_STYLE_MAP_ENTRY(border_style, BorderStyle),
//// COMPUTED_STYLE_MAP_ENTRY(border_top, BorderTop),
COMPUTED_STYLE_MAP_ENTRY(border_top_color, BorderTopColor),
COMPUTED_STYLE_MAP_ENTRY(border_top_style, BorderTopStyle),
COMPUTED_STYLE_MAP_ENTRY(border_top_width, BorderTopWidth),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(border_top_width, BorderTopWidth),
//// COMPUTED_STYLE_MAP_ENTRY(border_width, BorderWidth),
COMPUTED_STYLE_MAP_ENTRY(bottom, Bottom),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(bottom, Bottom),
COMPUTED_STYLE_MAP_ENTRY(caption_side, CaptionSide),
COMPUTED_STYLE_MAP_ENTRY(clear, Clear),
COMPUTED_STYLE_MAP_ENTRY(clip, Clip),
@ -4105,8 +4105,8 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
COMPUTED_STYLE_MAP_ENTRY(font_style, FontStyle),
COMPUTED_STYLE_MAP_ENTRY(font_variant, FontVariant),
COMPUTED_STYLE_MAP_ENTRY(font_weight, FontWeight),
COMPUTED_STYLE_MAP_ENTRY(height, Height),
COMPUTED_STYLE_MAP_ENTRY(left, Left),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(height, Height),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(left, Left),
COMPUTED_STYLE_MAP_ENTRY(letter_spacing, LetterSpacing),
COMPUTED_STYLE_MAP_ENTRY(line_height, LineHeight),
//// COMPUTED_STYLE_MAP_ENTRY(list_style, ListStyle),
@ -4114,16 +4114,16 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
COMPUTED_STYLE_MAP_ENTRY(list_style_position, ListStylePosition),
COMPUTED_STYLE_MAP_ENTRY(list_style_type, ListStyleType),
//// COMPUTED_STYLE_MAP_ENTRY(margin, Margin),
COMPUTED_STYLE_MAP_ENTRY(margin_bottom, MarginBottomWidth),
COMPUTED_STYLE_MAP_ENTRY(margin_left, MarginLeftWidth),
COMPUTED_STYLE_MAP_ENTRY(margin_right, MarginRightWidth),
COMPUTED_STYLE_MAP_ENTRY(margin_top, MarginTopWidth),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(margin_bottom, MarginBottomWidth),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(margin_left, MarginLeftWidth),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(margin_right, MarginRightWidth),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(margin_top, MarginTopWidth),
COMPUTED_STYLE_MAP_ENTRY(marker_offset, MarkerOffset),
// COMPUTED_STYLE_MAP_ENTRY(marks, Marks),
COMPUTED_STYLE_MAP_ENTRY(max_height, MaxHeight),
COMPUTED_STYLE_MAP_ENTRY(max_width, MaxWidth),
COMPUTED_STYLE_MAP_ENTRY(min_height, MinHeight),
COMPUTED_STYLE_MAP_ENTRY(min_width, MinWidth),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(max_height, MaxHeight),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(max_width, MaxWidth),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(min_height, MinHeight),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(min_width, MinWidth),
COMPUTED_STYLE_MAP_ENTRY(ime_mode, IMEMode),
COMPUTED_STYLE_MAP_ENTRY(opacity, Opacity),
// COMPUTED_STYLE_MAP_ENTRY(orphans, Orphans),
@ -4136,10 +4136,10 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
COMPUTED_STYLE_MAP_ENTRY(overflow_x, OverflowX),
COMPUTED_STYLE_MAP_ENTRY(overflow_y, OverflowY),
//// COMPUTED_STYLE_MAP_ENTRY(padding, Padding),
COMPUTED_STYLE_MAP_ENTRY(padding_bottom, PaddingBottom),
COMPUTED_STYLE_MAP_ENTRY(padding_left, PaddingLeft),
COMPUTED_STYLE_MAP_ENTRY(padding_right, PaddingRight),
COMPUTED_STYLE_MAP_ENTRY(padding_top, PaddingTop),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(padding_bottom, PaddingBottom),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(padding_left, PaddingLeft),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(padding_right, PaddingRight),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(padding_top, PaddingTop),
// COMPUTED_STYLE_MAP_ENTRY(page, Page),
COMPUTED_STYLE_MAP_ENTRY(page_break_after, PageBreakAfter),
COMPUTED_STYLE_MAP_ENTRY(page_break_before, PageBreakBefore),
@ -4152,7 +4152,7 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
COMPUTED_STYLE_MAP_ENTRY(position, Position),
COMPUTED_STYLE_MAP_ENTRY(quotes, Quotes),
// COMPUTED_STYLE_MAP_ENTRY(richness, Richness),
COMPUTED_STYLE_MAP_ENTRY(right, Right),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(right, Right),
//// COMPUTED_STYLE_MAP_ENTRY(size, Size),
// COMPUTED_STYLE_MAP_ENTRY(speak, Speak),
// COMPUTED_STYLE_MAP_ENTRY(speak_header, SpeakHeader),
@ -4163,10 +4163,10 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
COMPUTED_STYLE_MAP_ENTRY(table_layout, TableLayout),
COMPUTED_STYLE_MAP_ENTRY(text_align, TextAlign),
COMPUTED_STYLE_MAP_ENTRY(text_decoration, TextDecoration),
COMPUTED_STYLE_MAP_ENTRY(text_indent, TextIndent),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(text_indent, TextIndent),
COMPUTED_STYLE_MAP_ENTRY(text_shadow, TextShadow),
COMPUTED_STYLE_MAP_ENTRY(text_transform, TextTransform),
COMPUTED_STYLE_MAP_ENTRY(top, Top),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(top, Top),
COMPUTED_STYLE_MAP_ENTRY(unicode_bidi, UnicodeBidi),
COMPUTED_STYLE_MAP_ENTRY(vertical_align, VerticalAlign),
COMPUTED_STYLE_MAP_ENTRY(visibility, Visibility),
@ -4174,7 +4174,7 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
// COMPUTED_STYLE_MAP_ENTRY(volume, Volume),
COMPUTED_STYLE_MAP_ENTRY(white_space, WhiteSpace),
// COMPUTED_STYLE_MAP_ENTRY(widows, Widows),
COMPUTED_STYLE_MAP_ENTRY(width, Width),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(width, Width),
COMPUTED_STYLE_MAP_ENTRY(word_spacing, WordSpacing),
COMPUTED_STYLE_MAP_ENTRY(z_index, ZIndex),
@ -4192,10 +4192,10 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
COMPUTED_STYLE_MAP_ENTRY(border_left_colors, BorderLeftColors),
COMPUTED_STYLE_MAP_ENTRY(border_right_colors, BorderRightColors),
COMPUTED_STYLE_MAP_ENTRY(border_top_colors, BorderTopColors),
COMPUTED_STYLE_MAP_ENTRY(_moz_border_radius_bottomLeft, BorderRadiusBottomLeft),
COMPUTED_STYLE_MAP_ENTRY(_moz_border_radius_bottomRight,BorderRadiusBottomRight),
COMPUTED_STYLE_MAP_ENTRY(_moz_border_radius_topLeft, BorderRadiusTopLeft),
COMPUTED_STYLE_MAP_ENTRY(_moz_border_radius_topRight, BorderRadiusTopRight),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_border_radius_bottomLeft, BorderRadiusBottomLeft),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_border_radius_bottomRight,BorderRadiusBottomRight),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_border_radius_topLeft, BorderRadiusTopLeft),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_border_radius_topRight, BorderRadiusTopRight),
COMPUTED_STYLE_MAP_ENTRY(box_align, BoxAlign),
COMPUTED_STYLE_MAP_ENTRY(box_direction, BoxDirection),
COMPUTED_STYLE_MAP_ENTRY(box_flex, BoxFlex),
@ -4214,13 +4214,13 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
COMPUTED_STYLE_MAP_ENTRY(float_edge, FloatEdge),
COMPUTED_STYLE_MAP_ENTRY(force_broken_image_icon, ForceBrokenImageIcon),
COMPUTED_STYLE_MAP_ENTRY(image_region, ImageRegion),
COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_bottomLeft, OutlineRadiusBottomLeft),
COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_bottomRight,OutlineRadiusBottomRight),
COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_topLeft, OutlineRadiusTopLeft),
COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_topRight, OutlineRadiusTopRight),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_outline_radius_bottomLeft, OutlineRadiusBottomLeft),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_outline_radius_bottomRight,OutlineRadiusBottomRight),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_outline_radius_topLeft, OutlineRadiusTopLeft),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_outline_radius_topRight, OutlineRadiusTopRight),
COMPUTED_STYLE_MAP_ENTRY(stack_sizing, StackSizing),
COMPUTED_STYLE_MAP_ENTRY(_moz_transform, MozTransform),
COMPUTED_STYLE_MAP_ENTRY(_moz_transform_origin, MozTransformOrigin),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_transform, MozTransform),
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_transform_origin, MozTransformOrigin),
COMPUTED_STYLE_MAP_ENTRY(user_focus, UserFocus),
COMPUTED_STYLE_MAP_ENTRY(user_input, UserInput),
COMPUTED_STYLE_MAP_ENTRY(user_modify, UserModify),

Просмотреть файл

@ -77,7 +77,10 @@ public:
static void Shutdown();
private:
void FlushPendingReflows();
void AssertFlushedPendingReflows() {
NS_ASSERTION(mFlushedPendingReflows,
"property getter should have been marked layout-dependent");
}
#define STYLE_STRUCT(name_, checkdata_cb_, ctor_args_) \
const nsStyle##name_ * GetStyle##name_() { \
@ -398,6 +401,7 @@ private:
nsCSSProperty mProperty;
ComputeMethod mGetter;
PRBool mNeedsLayoutFlush;
};
static const ComputedStyleMapEntry* GetQueryablePropertyMap(PRUint32* aLength);
@ -437,6 +441,10 @@ private:
nsIPresShell* mPresShell;
PRInt32 mAppUnitsPerInch; /* For unit conversions */
#ifdef DEBUG
PRBool mFlushedPendingReflows;
#endif
};
#endif /* nsComputedDOMStyle_h__ */