Implement multiple background layers, implement fallback background color, and make -moz-background-inline-policy no longer be part of the background shorthand. (Bug 322475) r+sr=roc,bzbarsky
|
@ -526,8 +526,8 @@ nsBGColorTextAttr::GetColor(nsIFrame *aFrame, nscolor *aColor)
|
||||||
{
|
{
|
||||||
const nsStyleBackground *styleBackground = aFrame->GetStyleBackground();
|
const nsStyleBackground *styleBackground = aFrame->GetStyleBackground();
|
||||||
|
|
||||||
if (!styleBackground->IsTransparent()) {
|
if (NS_GET_A(styleBackground->mFallbackBackgroundColor) > 0) {
|
||||||
*aColor = styleBackground->mBackgroundColor;
|
*aColor = styleBackground->mFallbackBackgroundColor;
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1941,8 +1941,7 @@ nsGenericHTMLElement::MapBackgroundInto(const nsMappedAttributes* aAttributes,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nsPresContext* presContext = aData->mPresContext;
|
nsPresContext* presContext = aData->mPresContext;
|
||||||
if (aData->mColorData->mBackImage.GetUnit() == eCSSUnit_Null &&
|
if (!aData->mColorData->mBackImage && presContext->UseDocumentColors()) {
|
||||||
presContext->UseDocumentColors()) {
|
|
||||||
// background
|
// background
|
||||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::background);
|
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::background);
|
||||||
if (value && value->Type() == nsAttrValue::eString) {
|
if (value && value->Type() == nsAttrValue::eString) {
|
||||||
|
@ -1972,7 +1971,11 @@ nsGenericHTMLElement::MapBackgroundInto(const nsMappedAttributes* aAttributes,
|
||||||
doc->NodePrincipal(), doc);
|
doc->NodePrincipal(), doc);
|
||||||
buffer->Release();
|
buffer->Release();
|
||||||
if (NS_LIKELY(img != 0)) {
|
if (NS_LIKELY(img != 0)) {
|
||||||
aData->mColorData->mBackImage.SetImageValue(img);
|
// Use nsRuleDataColor's temporary mTempBackImage to
|
||||||
|
// make a value list.
|
||||||
|
aData->mColorData->mTempBackImage.mValue.SetImageValue(img);
|
||||||
|
aData->mColorData->mBackImage =
|
||||||
|
&aData->mColorData->mTempBackImage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1980,7 +1983,10 @@ nsGenericHTMLElement::MapBackgroundInto(const nsMappedAttributes* aAttributes,
|
||||||
else if (presContext->CompatibilityMode() == eCompatibility_NavQuirks) {
|
else if (presContext->CompatibilityMode() == eCompatibility_NavQuirks) {
|
||||||
// in NavQuirks mode, allow the empty string to set the
|
// in NavQuirks mode, allow the empty string to set the
|
||||||
// background to empty
|
// background to empty
|
||||||
aData->mColorData->mBackImage.SetNoneValue();
|
// Use nsRuleDataColor's temporary mTempBackImage to make a value list.
|
||||||
|
aData->mColorData->mBackImage = nsnull;
|
||||||
|
aData->mColorData->mTempBackImage.mValue.SetNoneValue();
|
||||||
|
aData->mColorData->mBackImage = &aData->mColorData->mTempBackImage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1993,12 +1999,16 @@ nsGenericHTMLElement::MapBGColorInto(const nsMappedAttributes* aAttributes,
|
||||||
if (!(aData->mSIDs & NS_STYLE_INHERIT_BIT(Background)))
|
if (!(aData->mSIDs & NS_STYLE_INHERIT_BIT(Background)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (aData->mColorData->mBackColor.GetUnit() == eCSSUnit_Null &&
|
if (aData->mColorData->mBackColor.mXValue.GetUnit() == eCSSUnit_Null &&
|
||||||
aData->mPresContext->UseDocumentColors()) {
|
aData->mPresContext->UseDocumentColors()) {
|
||||||
|
NS_ASSERTION(aData->mColorData->mBackColor.mYValue.GetUnit() ==
|
||||||
|
eCSSUnit_Null,
|
||||||
|
"half a property?");
|
||||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::bgcolor);
|
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::bgcolor);
|
||||||
nscolor color;
|
nscolor color;
|
||||||
if (value && value->GetColorValue(color)) {
|
if (value && value->GetColorValue(color)) {
|
||||||
aData->mColorData->mBackColor.SetColorValue(color);
|
aData->mColorData->mBackColor.mXValue.SetColorValue(color);
|
||||||
|
aData->mColorData->mBackColor.mYValue.SetColorValue(color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -377,10 +377,15 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
|
||||||
if (!value) {
|
if (!value) {
|
||||||
value = aAttributes->GetAttr(nsGkAtoms::background);
|
value = aAttributes->GetAttr(nsGkAtoms::background);
|
||||||
}
|
}
|
||||||
if (value && aData->mColorData->mBackColor.GetUnit() == eCSSUnit_Null) {
|
if (value &&
|
||||||
|
aData->mColorData->mBackColor.mXValue.GetUnit() == eCSSUnit_Null) {
|
||||||
|
NS_ASSERTION(aData->mColorData->mBackColor.mYValue.GetUnit()
|
||||||
|
== eCSSUnit_Null,
|
||||||
|
"half a property?");
|
||||||
nscolor color;
|
nscolor color;
|
||||||
if (value->GetColorValue(color)) {
|
if (value->GetColorValue(color)) {
|
||||||
aData->mColorData->mBackColor.SetColorValue(color);
|
aData->mColorData->mBackColor.mXValue.SetColorValue(color);
|
||||||
|
aData->mColorData->mBackColor.mYValue.SetColorValue(color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -676,6 +676,16 @@ public:
|
||||||
mContext->Save();
|
mContext->Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Reset(gfxContext *aContext) {
|
||||||
|
// Do the equivalent of destroying and re-creating this object.
|
||||||
|
NS_PRECONDITION(aContext, "must provide a context");
|
||||||
|
if (mContext) {
|
||||||
|
mContext->Restore();
|
||||||
|
}
|
||||||
|
mContext = aContext;
|
||||||
|
mContext->Save();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gfxContext *mContext;
|
gfxContext *mContext;
|
||||||
};
|
};
|
||||||
|
|
|
@ -262,6 +262,17 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Local functions */
|
/* Local functions */
|
||||||
|
static void PaintBackgroundLayer(nsPresContext* aPresContext,
|
||||||
|
nsIRenderingContext& aRenderingContext,
|
||||||
|
nsIFrame* aForFrame,
|
||||||
|
const nsRect& aDirtyRect,
|
||||||
|
const nsRect& aBorderArea,
|
||||||
|
const nsRect& aBGClipRect,
|
||||||
|
const nsStyleBackground& aBackground,
|
||||||
|
const nsStyleBackground::Layer& aLayer,
|
||||||
|
const nsStyleBorder& aBorder,
|
||||||
|
PRBool aUsePrintSettings);
|
||||||
|
|
||||||
static void DrawBorderImage(nsPresContext* aPresContext,
|
static void DrawBorderImage(nsPresContext* aPresContext,
|
||||||
nsIRenderingContext& aRenderingContext,
|
nsIRenderingContext& aRenderingContext,
|
||||||
nsIFrame* aForFrame,
|
nsIFrame* aForFrame,
|
||||||
|
@ -800,35 +811,29 @@ nsCSSRendering::PaintFocus(nsPresContext* aPresContext,
|
||||||
* Points are returned relative to aOriginBounds.
|
* Points are returned relative to aOriginBounds.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
ComputeBackgroundAnchorPoint(const nsStyleBackground& aColor,
|
ComputeBackgroundAnchorPoint(const nsStyleBackground::Layer& aLayer,
|
||||||
const nsSize& aOriginBounds,
|
const nsSize& aOriginBounds,
|
||||||
const nsSize& aImageSize,
|
const nsSize& aImageSize,
|
||||||
nsPoint* aTopLeft,
|
nsPoint* aTopLeft,
|
||||||
nsPoint* aAnchorPoint)
|
nsPoint* aAnchorPoint)
|
||||||
{
|
{
|
||||||
if (NS_STYLE_BG_X_POSITION_LENGTH & aColor.mBackgroundFlags) {
|
if (!aLayer.mPosition.mXIsPercent) {
|
||||||
aTopLeft->x = aAnchorPoint->x = aColor.mBackgroundXPosition.mCoord;
|
aTopLeft->x = aAnchorPoint->x = aLayer.mPosition.mXPosition.mCoord;
|
||||||
}
|
}
|
||||||
else if (NS_STYLE_BG_X_POSITION_PERCENT & aColor.mBackgroundFlags) {
|
else {
|
||||||
double percent = aColor.mBackgroundXPosition.mFloat;
|
double percent = aLayer.mPosition.mXPosition.mFloat;
|
||||||
aAnchorPoint->x = NSToCoordRound(percent*aOriginBounds.width);
|
aAnchorPoint->x = NSToCoordRound(percent*aOriginBounds.width);
|
||||||
aTopLeft->x = NSToCoordRound(percent*(aOriginBounds.width - aImageSize.width));
|
aTopLeft->x = NSToCoordRound(percent*(aOriginBounds.width - aImageSize.width));
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
aTopLeft->x = aAnchorPoint->x = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_STYLE_BG_Y_POSITION_LENGTH & aColor.mBackgroundFlags) {
|
if (!aLayer.mPosition.mYIsPercent) {
|
||||||
aTopLeft->y = aAnchorPoint->y = aColor.mBackgroundYPosition.mCoord;
|
aTopLeft->y = aAnchorPoint->y = aLayer.mPosition.mYPosition.mCoord;
|
||||||
}
|
}
|
||||||
else if (NS_STYLE_BG_Y_POSITION_PERCENT & aColor.mBackgroundFlags) {
|
else {
|
||||||
double percent = aColor.mBackgroundYPosition.mFloat;
|
double percent = aLayer.mPosition.mYPosition.mFloat;
|
||||||
aAnchorPoint->y = NSToCoordRound(percent*aOriginBounds.height);
|
aAnchorPoint->y = NSToCoordRound(percent*aOriginBounds.height);
|
||||||
aTopLeft->y = NSToCoordRound(percent*(aOriginBounds.height - aImageSize.height));
|
aTopLeft->y = NSToCoordRound(percent*(aOriginBounds.height - aImageSize.height));
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
aTopLeft->y = aAnchorPoint->y = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsStyleContext*
|
nsStyleContext*
|
||||||
|
@ -1342,6 +1347,103 @@ IsSolidBorder(const nsStyleBorder& aBorder)
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PRBool
|
||||||
|
UseImageRequestForBackground(imgIRequest *aRequest)
|
||||||
|
{
|
||||||
|
if (!aRequest)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
PRUint32 status = imgIRequest::STATUS_ERROR;
|
||||||
|
aRequest->GetImageStatus(&status);
|
||||||
|
|
||||||
|
return (status & imgIRequest::STATUS_FRAME_COMPLETE) &&
|
||||||
|
(status & imgIRequest::STATUS_SIZE_AVAILABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
SetupDirtyRects(const nsRect& aBGClipArea, const nsRect& aCallerDirtyRect,
|
||||||
|
nscoord aAppUnitsPerPixel,
|
||||||
|
/* OUT: */
|
||||||
|
nsRect* aDirtyRect, gfxRect* aDirtyRectGfx)
|
||||||
|
{
|
||||||
|
aDirtyRect->IntersectRect(aBGClipArea, aCallerDirtyRect);
|
||||||
|
|
||||||
|
// Compute the Thebes equivalent of the dirtyRect.
|
||||||
|
*aDirtyRectGfx = RectToGfxRect(*aDirtyRect, aAppUnitsPerPixel);
|
||||||
|
NS_WARN_IF_FALSE(aDirtyRect->IsEmpty() || !aDirtyRectGfx->IsEmpty(),
|
||||||
|
"converted dirty rect should not be empty");
|
||||||
|
NS_ABORT_IF_FALSE(!aDirtyRect->IsEmpty() || aDirtyRectGfx->IsEmpty(),
|
||||||
|
"second should be empty if first is");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
SetupBackgroundClip(gfxContext *aCtx, PRUint8 aBackgroundClip,
|
||||||
|
nsIFrame* aForFrame, const nsRect& aBorderArea,
|
||||||
|
const nsRect& aCallerDirtyRect, PRBool aHaveRoundedCorners,
|
||||||
|
const gfxCornerSizes& aBGRadii, nscoord aAppUnitsPerPixel,
|
||||||
|
gfxContextAutoSaveRestore* aAutoSR,
|
||||||
|
/* OUT: */
|
||||||
|
nsRect* aBGClipArea, nsRect* aDirtyRect,
|
||||||
|
gfxRect* aDirtyRectGfx)
|
||||||
|
{
|
||||||
|
*aBGClipArea = aBorderArea;
|
||||||
|
PRBool radiiAreOuter = PR_TRUE;
|
||||||
|
gfxCornerSizes clippedRadii = aBGRadii;
|
||||||
|
if (aBackgroundClip != NS_STYLE_BG_CLIP_BORDER) {
|
||||||
|
NS_ASSERTION(aBackgroundClip == NS_STYLE_BG_CLIP_PADDING,
|
||||||
|
"unexpected background-clip");
|
||||||
|
nsMargin border = aForFrame->GetUsedBorder();
|
||||||
|
aForFrame->ApplySkipSides(border);
|
||||||
|
aBGClipArea->Deflate(border);
|
||||||
|
|
||||||
|
if (aHaveRoundedCorners) {
|
||||||
|
gfxFloat borderSizes[4] = {
|
||||||
|
border.top / aAppUnitsPerPixel, border.right / aAppUnitsPerPixel,
|
||||||
|
border.bottom / aAppUnitsPerPixel, border.left / aAppUnitsPerPixel
|
||||||
|
};
|
||||||
|
nsCSSBorderRenderer::ComputeInnerRadii(aBGRadii, borderSizes,
|
||||||
|
&clippedRadii);
|
||||||
|
radiiAreOuter = PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupDirtyRects(*aBGClipArea, aCallerDirtyRect, aAppUnitsPerPixel,
|
||||||
|
aDirtyRect, aDirtyRectGfx);
|
||||||
|
|
||||||
|
if (aDirtyRectGfx->IsEmpty()) {
|
||||||
|
// Our caller won't draw anything under this condition, so no need
|
||||||
|
// to set more up.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have rounded corners, clip all subsequent drawing to the
|
||||||
|
// rounded rectangle defined by bgArea and bgRadii (we don't know
|
||||||
|
// whether the rounded corners intrude on the dirtyRect or not).
|
||||||
|
// Do not do this if we have a caller-provided clip rect --
|
||||||
|
// as above with bgArea, arguably a bug, but table painting seems
|
||||||
|
// to depend on it.
|
||||||
|
|
||||||
|
if (aHaveRoundedCorners) {
|
||||||
|
gfxRect bgAreaGfx(RectToGfxRect(*aBGClipArea, aAppUnitsPerPixel));
|
||||||
|
bgAreaGfx.Round();
|
||||||
|
bgAreaGfx.Condition();
|
||||||
|
|
||||||
|
if (bgAreaGfx.IsEmpty()) {
|
||||||
|
// I think it's become possible to hit this since
|
||||||
|
// http://hg.mozilla.org/mozilla-central/rev/50e934e4979b landed.
|
||||||
|
NS_WARNING("converted background area should not be empty");
|
||||||
|
// Make our caller not do anything.
|
||||||
|
aDirtyRectGfx->size.SizeTo(0.0, 0.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aAutoSR->Reset(aCtx);
|
||||||
|
aCtx->NewPath();
|
||||||
|
aCtx->RoundedRectangle(bgAreaGfx, clippedRadii, radiiAreOuter);
|
||||||
|
aCtx->Clip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||||
nsIRenderingContext& aRenderingContext,
|
nsIRenderingContext& aRenderingContext,
|
||||||
|
@ -1382,11 +1484,16 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||||
drawBackgroundColor = aPresContext->GetBackgroundColorDraw();
|
drawBackgroundColor = aPresContext->GetBackgroundColorDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((aColor.mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE) ||
|
nsStyleBackground::Image bottomImage(aColor.BottomLayer().mImage);
|
||||||
!aColor.mBackgroundImage) {
|
PRBool useFallbackColor = PR_FALSE;
|
||||||
NS_ASSERTION((aColor.mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE) &&
|
if (bottomImage.mSpecified) {
|
||||||
!aColor.mBackgroundImage, "background flags/image mismatch");
|
if (!drawBackgroundImage ||
|
||||||
drawBackgroundImage = PR_FALSE;
|
!UseImageRequestForBackground(bottomImage.mRequest)) {
|
||||||
|
bottomImage.mRequest = nsnull;
|
||||||
|
}
|
||||||
|
useFallbackColor = bottomImage.mRequest == nsnull;
|
||||||
|
} else {
|
||||||
|
NS_ASSERTION(bottomImage.mRequest == nsnull, "malformed image struct");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If GetBackgroundColorDraw() is false, we are still expected to
|
// If GetBackgroundColorDraw() is false, we are still expected to
|
||||||
|
@ -1395,7 +1502,8 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||||
// color was specified.
|
// color was specified.
|
||||||
nscolor bgColor;
|
nscolor bgColor;
|
||||||
if (drawBackgroundColor) {
|
if (drawBackgroundColor) {
|
||||||
bgColor = aColor.mBackgroundColor;
|
bgColor = useFallbackColor ? aColor.mFallbackBackgroundColor
|
||||||
|
: aColor.mBackgroundColor;
|
||||||
if (NS_GET_A(bgColor) == 0)
|
if (NS_GET_A(bgColor) == 0)
|
||||||
drawBackgroundColor = PR_FALSE;
|
drawBackgroundColor = PR_FALSE;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1415,10 +1523,8 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||||
nscoord appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
|
nscoord appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
|
||||||
|
|
||||||
// Same coordinate space as aBorderArea & aBGClipRect
|
// Same coordinate space as aBorderArea & aBGClipRect
|
||||||
nsRect bgArea;
|
|
||||||
gfxCornerSizes bgRadii;
|
gfxCornerSizes bgRadii;
|
||||||
PRBool haveRoundedCorners;
|
PRBool haveRoundedCorners;
|
||||||
PRBool radiiAreOuter = PR_TRUE;
|
|
||||||
{
|
{
|
||||||
nscoord radii[8];
|
nscoord radii[8];
|
||||||
haveRoundedCorners =
|
haveRoundedCorners =
|
||||||
|
@ -1429,79 +1535,38 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||||
appUnitsPerPixel, &bgRadii);
|
appUnitsPerPixel, &bgRadii);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The background is rendered over the 'background-clip' area,
|
|
||||||
// which is normally equal to the border area but may be reduced
|
|
||||||
// to the padding area by CSS. Also, if the border is solid, we
|
|
||||||
// don't need to draw outside the padding area. In either case,
|
|
||||||
// if the borders are rounded, make sure we use the same inner
|
|
||||||
// radii as the border code will.
|
|
||||||
bgArea = aBorderArea;
|
|
||||||
if (aColor.mBackgroundClip != NS_STYLE_BG_CLIP_BORDER ||
|
|
||||||
IsSolidBorder(aBorder)) {
|
|
||||||
nsMargin border = aForFrame->GetUsedBorder();
|
|
||||||
aForFrame->ApplySkipSides(border);
|
|
||||||
bgArea.Deflate(border);
|
|
||||||
if (haveRoundedCorners) {
|
|
||||||
gfxCornerSizes outerRadii = bgRadii;
|
|
||||||
gfxFloat borderSizes[4] = {
|
|
||||||
border.top / appUnitsPerPixel, border.right / appUnitsPerPixel,
|
|
||||||
border.bottom / appUnitsPerPixel, border.left / appUnitsPerPixel
|
|
||||||
};
|
|
||||||
nsCSSBorderRenderer::ComputeInnerRadii(outerRadii, borderSizes,
|
|
||||||
&bgRadii);
|
|
||||||
radiiAreOuter = PR_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The 'bgClipArea' (used only by the image tiling logic, far below)
|
// The 'bgClipArea' (used only by the image tiling logic, far below)
|
||||||
// is the caller-provided aBGClipRect if any, or else the bgArea
|
// is the caller-provided aBGClipRect if any, or else the area
|
||||||
// computed above. (Arguably it should be the intersection, but
|
// determined by the value of 'background-clip' in
|
||||||
// that breaks the table painter -- in particular, honoring the
|
// SetupCurrentBackgroundClip. (Arguably it should be the
|
||||||
// bgArea when we have aBGClipRect breaks reftests/bugs/403429-1[ab].)
|
// intersection, but that breaks the table painter -- in particular,
|
||||||
// The dirtyRect is the intersection of that rectangle with the
|
// taking the intersection breaks reftests/bugs/403429-1[ab].)
|
||||||
// caller-provided aDirtyRect. If the dirtyRect is empty there is
|
nsRect bgClipArea, dirtyRect;
|
||||||
// nothing to draw.
|
gfxRect dirtyRectGfx;
|
||||||
|
PRUint8 currentBackgroundClip;
|
||||||
nsRect bgClipArea;
|
PRBool isSolidBorder;
|
||||||
if (aBGClipRect)
|
|
||||||
bgClipArea = *aBGClipRect;
|
|
||||||
else
|
|
||||||
bgClipArea = bgArea;
|
|
||||||
|
|
||||||
nsRect dirtyRect;
|
|
||||||
dirtyRect.IntersectRect(bgClipArea, aDirtyRect);
|
|
||||||
|
|
||||||
if (dirtyRect.IsEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Compute the Thebes equivalent of the dirtyRect.
|
|
||||||
gfxRect dirtyRectGfx(RectToGfxRect(dirtyRect, appUnitsPerPixel));
|
|
||||||
if (dirtyRectGfx.IsEmpty()) {
|
|
||||||
NS_WARNING("converted dirty rect should not be empty");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have rounded corners, clip all subsequent drawing to the
|
|
||||||
// rounded rectangle defined by bgArea and bgRadii (we don't know
|
|
||||||
// whether the rounded corners intrude on the dirtyRect or not).
|
|
||||||
// Do not do this if we have a caller-provided clip rect --
|
|
||||||
// as above with bgArea, arguably a bug, but table painting seems
|
|
||||||
// to depend on it.
|
|
||||||
|
|
||||||
gfxContextAutoSaveRestore autoSR;
|
gfxContextAutoSaveRestore autoSR;
|
||||||
if (haveRoundedCorners && !aBGClipRect) {
|
if (aBGClipRect) {
|
||||||
gfxRect bgAreaGfx(RectToGfxRect(bgArea, appUnitsPerPixel));
|
bgClipArea = *aBGClipRect;
|
||||||
bgAreaGfx.Round();
|
SetupDirtyRects(bgClipArea, aDirtyRect, appUnitsPerPixel,
|
||||||
bgAreaGfx.Condition();
|
&dirtyRect, &dirtyRectGfx);
|
||||||
if (bgAreaGfx.IsEmpty()) {
|
} else {
|
||||||
NS_WARNING("converted background area should not be empty");
|
// The background is rendered over the 'background-clip' area,
|
||||||
return;
|
// which is normally equal to the border area but may be reduced
|
||||||
}
|
// to the padding area by CSS. Also, if the border is solid, we
|
||||||
|
// don't need to draw outside the padding area. In either case,
|
||||||
autoSR.SetContext(ctx);
|
// if the borders are rounded, make sure we use the same inner
|
||||||
ctx->NewPath();
|
// radii as the border code will.
|
||||||
ctx->RoundedRectangle(bgAreaGfx, bgRadii, radiiAreOuter);
|
// The background-color is drawn based on the bottom
|
||||||
ctx->Clip();
|
// background-clip.
|
||||||
|
currentBackgroundClip = aColor.BottomLayer().mClip;
|
||||||
|
isSolidBorder = IsSolidBorder(aBorder);
|
||||||
|
if (isSolidBorder)
|
||||||
|
currentBackgroundClip = NS_STYLE_BG_CLIP_PADDING;
|
||||||
|
SetupBackgroundClip(ctx, currentBackgroundClip, aForFrame,
|
||||||
|
aBorderArea, aDirtyRect, haveRoundedCorners,
|
||||||
|
bgRadii, appUnitsPerPixel, &autoSR,
|
||||||
|
&bgClipArea, &dirtyRect, &dirtyRectGfx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we might be using a background color, go ahead and set it now.
|
// If we might be using a background color, go ahead and set it now.
|
||||||
|
@ -1512,9 +1577,11 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||||
// neither a background image nor a color, we wouldn't have gotten
|
// neither a background image nor a color, we wouldn't have gotten
|
||||||
// this far.)
|
// this far.)
|
||||||
if (!drawBackgroundImage) {
|
if (!drawBackgroundImage) {
|
||||||
ctx->NewPath();
|
if (!dirtyRectGfx.IsEmpty()) {
|
||||||
ctx->Rectangle(dirtyRectGfx, PR_TRUE);
|
ctx->NewPath();
|
||||||
ctx->Fill();
|
ctx->Rectangle(dirtyRectGfx, PR_TRUE);
|
||||||
|
ctx->Fill();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1523,21 +1590,83 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||||
// association of the style data with the frame.
|
// association of the style data with the frame.
|
||||||
aPresContext->SetupBackgroundImageLoaders(aForFrame, &aColor);
|
aPresContext->SetupBackgroundImageLoaders(aForFrame, &aColor);
|
||||||
|
|
||||||
imgIRequest *req = aColor.mBackgroundImage;
|
if (bottomImage.mRequest &&
|
||||||
|
aColor.BottomLayer().mRepeat == NS_STYLE_BG_REPEAT_XY &&
|
||||||
|
drawBackgroundColor) {
|
||||||
|
nsCOMPtr<imgIContainer> image;
|
||||||
|
bottomImage.mRequest->GetImage(getter_AddRefs(image));
|
||||||
|
// If the image is completely opaque, we may not need to paint
|
||||||
|
// the background color.
|
||||||
|
nsCOMPtr<gfxIImageFrame> gfxImgFrame;
|
||||||
|
image->GetCurrentFrame(getter_AddRefs(gfxImgFrame));
|
||||||
|
if (gfxImgFrame) {
|
||||||
|
gfxImgFrame->GetNeedsBackground(&drawBackgroundColor);
|
||||||
|
if (!drawBackgroundColor) {
|
||||||
|
// If the current frame is smaller than its container, we
|
||||||
|
// need to paint the background color even if the frame
|
||||||
|
// itself is opaque.
|
||||||
|
nsIntSize iSize;
|
||||||
|
image->GetWidth(&iSize.width);
|
||||||
|
image->GetHeight(&iSize.height);
|
||||||
|
nsIntRect iframeRect;
|
||||||
|
gfxImgFrame->GetRect(iframeRect);
|
||||||
|
if (iSize.width != iframeRect.width ||
|
||||||
|
iSize.height != iframeRect.height) {
|
||||||
|
drawBackgroundColor = PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PRUint32 status = imgIRequest::STATUS_ERROR;
|
// The background color is rendered over the entire dirty area,
|
||||||
if (req)
|
// even if the image isn't.
|
||||||
req->GetImageStatus(&status);
|
if (drawBackgroundColor) {
|
||||||
|
if (!dirtyRectGfx.IsEmpty()) {
|
||||||
// While waiting for the image, draw a color, if any.
|
|
||||||
if (!req ||
|
|
||||||
!(status & imgIRequest::STATUS_FRAME_COMPLETE) ||
|
|
||||||
!(status & imgIRequest::STATUS_SIZE_AVAILABLE)) {
|
|
||||||
if (drawBackgroundColor) {
|
|
||||||
ctx->NewPath();
|
ctx->NewPath();
|
||||||
ctx->Rectangle(dirtyRectGfx, PR_TRUE);
|
ctx->Rectangle(dirtyRectGfx, PR_TRUE);
|
||||||
ctx->Fill();
|
ctx->Fill();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drawBackgroundImage) {
|
||||||
|
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, &aColor) {
|
||||||
|
const nsStyleBackground::Layer &layer = aColor.mLayers[i];
|
||||||
|
if (!aBGClipRect) {
|
||||||
|
PRUint8 newBackgroundClip =
|
||||||
|
isSolidBorder ? NS_STYLE_BG_CLIP_PADDING : layer.mClip;
|
||||||
|
if (currentBackgroundClip != newBackgroundClip) {
|
||||||
|
currentBackgroundClip = newBackgroundClip;
|
||||||
|
SetupBackgroundClip(ctx, currentBackgroundClip, aForFrame,
|
||||||
|
aBorderArea, aDirtyRect, haveRoundedCorners,
|
||||||
|
bgRadii, appUnitsPerPixel, &autoSR,
|
||||||
|
&bgClipArea, &dirtyRect, &dirtyRectGfx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!dirtyRectGfx.IsEmpty()) {
|
||||||
|
PaintBackgroundLayer(aPresContext, aRenderingContext, aForFrame,
|
||||||
|
dirtyRect, aBorderArea, bgClipArea, aColor,
|
||||||
|
layer, aBorder, aUsePrintSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
PaintBackgroundLayer(nsPresContext* aPresContext,
|
||||||
|
nsIRenderingContext& aRenderingContext,
|
||||||
|
nsIFrame* aForFrame,
|
||||||
|
const nsRect& aDirtyRect, // intersected with aBGClipRect
|
||||||
|
const nsRect& aBorderArea,
|
||||||
|
const nsRect& aBGClipRect,
|
||||||
|
const nsStyleBackground& aBackground,
|
||||||
|
const nsStyleBackground::Layer& aLayer,
|
||||||
|
const nsStyleBorder& aBorder,
|
||||||
|
PRBool aUsePrintSettings)
|
||||||
|
{
|
||||||
|
// Lookup the image
|
||||||
|
imgIRequest *req = aLayer.mImage.mRequest;
|
||||||
|
if (!UseImageRequestForBackground(req)) {
|
||||||
|
// There's no image or it's not ready to be painted.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1561,7 +1690,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||||
nsIFrame* geometryFrame = aForFrame;
|
nsIFrame* geometryFrame = aForFrame;
|
||||||
if (frameType == nsGkAtoms::inlineFrame ||
|
if (frameType == nsGkAtoms::inlineFrame ||
|
||||||
frameType == nsGkAtoms::positionedInlineFrame) {
|
frameType == nsGkAtoms::positionedInlineFrame) {
|
||||||
switch (aColor.mBackgroundInlinePolicy) {
|
switch (aBackground.mBackgroundInlinePolicy) {
|
||||||
case NS_STYLE_BG_INLINE_POLICY_EACH_BOX:
|
case NS_STYLE_BG_INLINE_POLICY_EACH_BOX:
|
||||||
bgOriginRect = nsRect(nsPoint(0,0), aBorderArea.Size());
|
bgOriginRect = nsRect(nsPoint(0,0), aBorderArea.Size());
|
||||||
break;
|
break;
|
||||||
|
@ -1588,71 +1717,25 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||||
|
|
||||||
// Background images are tiled over the 'background-clip' area
|
// Background images are tiled over the 'background-clip' area
|
||||||
// but the origin of the tiling is based on the 'background-origin' area
|
// but the origin of the tiling is based on the 'background-origin' area
|
||||||
if (aColor.mBackgroundOrigin != NS_STYLE_BG_ORIGIN_BORDER) {
|
if (aLayer.mOrigin != NS_STYLE_BG_ORIGIN_BORDER) {
|
||||||
nsMargin border = geometryFrame->GetUsedBorder();
|
nsMargin border = geometryFrame->GetUsedBorder();
|
||||||
geometryFrame->ApplySkipSides(border);
|
geometryFrame->ApplySkipSides(border);
|
||||||
bgOriginRect.Deflate(border);
|
bgOriginRect.Deflate(border);
|
||||||
if (aColor.mBackgroundOrigin != NS_STYLE_BG_ORIGIN_PADDING) {
|
if (aLayer.mOrigin != NS_STYLE_BG_ORIGIN_PADDING) {
|
||||||
nsMargin padding = geometryFrame->GetUsedPadding();
|
nsMargin padding = geometryFrame->GetUsedPadding();
|
||||||
geometryFrame->ApplySkipSides(padding);
|
geometryFrame->ApplySkipSides(padding);
|
||||||
bgOriginRect.Deflate(padding);
|
bgOriginRect.Deflate(padding);
|
||||||
NS_ASSERTION(aColor.mBackgroundOrigin == NS_STYLE_BG_ORIGIN_CONTENT,
|
NS_ASSERTION(aLayer.mOrigin == NS_STYLE_BG_ORIGIN_CONTENT,
|
||||||
"unknown background-origin value");
|
"unknown background-origin value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIntn repeat = aColor.mBackgroundRepeat;
|
|
||||||
switch (repeat) {
|
|
||||||
case NS_STYLE_BG_REPEAT_X:
|
|
||||||
break;
|
|
||||||
case NS_STYLE_BG_REPEAT_Y:
|
|
||||||
break;
|
|
||||||
case NS_STYLE_BG_REPEAT_XY:
|
|
||||||
if (drawBackgroundColor) {
|
|
||||||
// If the image is completely opaque, we may not need to paint
|
|
||||||
// the background color.
|
|
||||||
nsCOMPtr<gfxIImageFrame> gfxImgFrame;
|
|
||||||
image->GetCurrentFrame(getter_AddRefs(gfxImgFrame));
|
|
||||||
if (gfxImgFrame) {
|
|
||||||
gfxImgFrame->GetNeedsBackground(&drawBackgroundColor);
|
|
||||||
if (!drawBackgroundColor) {
|
|
||||||
// If the current frame is smaller than its container, we
|
|
||||||
// need to paint the background color even if the frame
|
|
||||||
// itself is opaque.
|
|
||||||
nsIntSize iSize;
|
|
||||||
image->GetWidth(&iSize.width);
|
|
||||||
image->GetHeight(&iSize.height);
|
|
||||||
nsIntRect iframeRect;
|
|
||||||
gfxImgFrame->GetRect(iframeRect);
|
|
||||||
if (iSize.width != iframeRect.width ||
|
|
||||||
iSize.height != iframeRect.height) {
|
|
||||||
drawBackgroundColor = PR_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NS_STYLE_BG_REPEAT_OFF:
|
|
||||||
default:
|
|
||||||
NS_ASSERTION(repeat == NS_STYLE_BG_REPEAT_OFF,
|
|
||||||
"unknown background-repeat value");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The background color is rendered over the entire dirty area,
|
|
||||||
// even if the image isn't.
|
|
||||||
if (drawBackgroundColor) {
|
|
||||||
ctx->NewPath();
|
|
||||||
ctx->Rectangle(dirtyRectGfx, PR_TRUE);
|
|
||||||
ctx->Fill();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the anchor point.
|
// Compute the anchor point.
|
||||||
//
|
//
|
||||||
// relative to aBorderArea.TopLeft() (which is where the top-left
|
// relative to aBorderArea.TopLeft() (which is where the top-left
|
||||||
// of aForFrame's border-box will be rendered)
|
// of aForFrame's border-box will be rendered)
|
||||||
nsPoint imageTopLeft, anchor;
|
nsPoint imageTopLeft, anchor;
|
||||||
if (NS_STYLE_BG_ATTACHMENT_FIXED == aColor.mBackgroundAttachment) {
|
if (NS_STYLE_BG_ATTACHMENT_FIXED == aLayer.mAttachment) {
|
||||||
// If it's a fixed background attachment, then the image is placed
|
// If it's a fixed background attachment, then the image is placed
|
||||||
// relative to the viewport, which is the area of the root frame
|
// relative to the viewport, which is the area of the root frame
|
||||||
// in a screen context or the page content frame in a print context.
|
// in a screen context or the page content frame in a print context.
|
||||||
|
@ -1686,7 +1769,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the anchor point, relative to the viewport.
|
// Get the anchor point, relative to the viewport.
|
||||||
ComputeBackgroundAnchorPoint(aColor, viewportArea.Size(), imageSize,
|
ComputeBackgroundAnchorPoint(aLayer, viewportArea.Size(), imageSize,
|
||||||
&imageTopLeft, &anchor);
|
&imageTopLeft, &anchor);
|
||||||
|
|
||||||
// Convert the anchor point from viewport coordinates to aForFrame
|
// Convert the anchor point from viewport coordinates to aForFrame
|
||||||
|
@ -1695,7 +1778,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||||
imageTopLeft += offset;
|
imageTopLeft += offset;
|
||||||
anchor += offset;
|
anchor += offset;
|
||||||
} else {
|
} else {
|
||||||
ComputeBackgroundAnchorPoint(aColor, bgOriginRect.Size(), imageSize,
|
ComputeBackgroundAnchorPoint(aLayer, bgOriginRect.Size(), imageSize,
|
||||||
&imageTopLeft, &anchor);
|
&imageTopLeft, &anchor);
|
||||||
imageTopLeft += bgOriginRect.TopLeft();
|
imageTopLeft += bgOriginRect.TopLeft();
|
||||||
anchor += bgOriginRect.TopLeft();
|
anchor += bgOriginRect.TopLeft();
|
||||||
|
@ -1703,18 +1786,19 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||||
|
|
||||||
nsRect destArea(imageTopLeft + aBorderArea.TopLeft(), imageSize);
|
nsRect destArea(imageTopLeft + aBorderArea.TopLeft(), imageSize);
|
||||||
nsRect fillArea = destArea;
|
nsRect fillArea = destArea;
|
||||||
|
PRIntn repeat = aLayer.mRepeat;
|
||||||
if (repeat & NS_STYLE_BG_REPEAT_X) {
|
if (repeat & NS_STYLE_BG_REPEAT_X) {
|
||||||
fillArea.x = bgClipArea.x;
|
fillArea.x = aBGClipRect.x;
|
||||||
fillArea.width = bgClipArea.width;
|
fillArea.width = aBGClipRect.width;
|
||||||
}
|
}
|
||||||
if (repeat & NS_STYLE_BG_REPEAT_Y) {
|
if (repeat & NS_STYLE_BG_REPEAT_Y) {
|
||||||
fillArea.y = bgClipArea.y;
|
fillArea.y = aBGClipRect.y;
|
||||||
fillArea.height = bgClipArea.height;
|
fillArea.height = aBGClipRect.height;
|
||||||
}
|
}
|
||||||
fillArea.IntersectRect(fillArea, bgClipArea);
|
fillArea.IntersectRect(fillArea, aBGClipRect);
|
||||||
|
|
||||||
nsLayoutUtils::DrawImage(&aRenderingContext, image,
|
nsLayoutUtils::DrawImage(&aRenderingContext, image,
|
||||||
destArea, fillArea, anchor + aBorderArea.TopLeft(), dirtyRect);
|
destArea, fillArea, anchor + aBorderArea.TopLeft(), aDirtyRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -497,7 +497,8 @@ nsDisplayBackground::IsOpaque(nsDisplayListBuilder* aBuilder) {
|
||||||
nsCSSRendering::FindBackground(mFrame->PresContext(), mFrame, &bg);
|
nsCSSRendering::FindBackground(mFrame->PresContext(), mFrame, &bg);
|
||||||
|
|
||||||
return (hasBG && NS_GET_A(bg->mBackgroundColor) == 255 &&
|
return (hasBG && NS_GET_A(bg->mBackgroundColor) == 255 &&
|
||||||
bg->mBackgroundClip == NS_STYLE_BG_CLIP_BORDER &&
|
// bottom layer's clip is used for the color
|
||||||
|
bg->BottomLayer().mClip == NS_STYLE_BG_CLIP_BORDER &&
|
||||||
!nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->
|
!nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->
|
||||||
mBorderRadius));
|
mBorderRadius));
|
||||||
}
|
}
|
||||||
|
@ -513,9 +514,10 @@ nsDisplayBackground::IsUniform(nsDisplayListBuilder* aBuilder) {
|
||||||
nsCSSRendering::FindBackground(mFrame->PresContext(), mFrame, &bg);
|
nsCSSRendering::FindBackground(mFrame->PresContext(), mFrame, &bg);
|
||||||
if (!hasBG)
|
if (!hasBG)
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
if ((bg->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE) &&
|
if (!bg->BottomLayer().mImage.mRequest &&
|
||||||
|
bg->mImageCount == 1 &&
|
||||||
!nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius) &&
|
!nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius) &&
|
||||||
bg->mBackgroundClip == NS_STYLE_BG_CLIP_BORDER)
|
bg->BottomLayer().mClip == NS_STYLE_BG_CLIP_BORDER)
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3066,9 +3066,10 @@ nsLayoutUtils::GetFrameTransparency(nsIFrame* aFrame) {
|
||||||
const nsStyleBackground* bg;
|
const nsStyleBackground* bg;
|
||||||
if (!nsCSSRendering::FindBackground(aFrame->PresContext(), aFrame, &bg))
|
if (!nsCSSRendering::FindBackground(aFrame->PresContext(), aFrame, &bg))
|
||||||
return eTransparencyTransparent;
|
return eTransparencyTransparent;
|
||||||
if (NS_GET_A(bg->mBackgroundColor) < 255)
|
if (NS_GET_A(bg->mBackgroundColor) < 255 ||
|
||||||
return eTransparencyTransparent;
|
NS_GET_A(bg->mFallbackBackgroundColor) < 255 ||
|
||||||
if (bg->mBackgroundClip != NS_STYLE_BG_CLIP_BORDER)
|
// bottom layer's clip is used for the color
|
||||||
|
bg->BottomLayer().mClip != NS_STYLE_BG_CLIP_BORDER)
|
||||||
return eTransparencyTransparent;
|
return eTransparencyTransparent;
|
||||||
return eTransparencyOpaque;
|
return eTransparencyOpaque;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1252,10 +1252,12 @@ void
|
||||||
nsPresContext::SetupBackgroundImageLoaders(nsIFrame* aFrame,
|
nsPresContext::SetupBackgroundImageLoaders(nsIFrame* aFrame,
|
||||||
const nsStyleBackground* aStyleBackground)
|
const nsStyleBackground* aStyleBackground)
|
||||||
{
|
{
|
||||||
nsRefPtr<nsImageLoader> loader =
|
nsRefPtr<nsImageLoader> loaders;
|
||||||
nsImageLoader::Create(aFrame, aStyleBackground->mBackgroundImage,
|
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, aStyleBackground) {
|
||||||
PR_FALSE, nsnull);
|
imgIRequest *image = aStyleBackground->mLayers[i].mImage.mRequest;
|
||||||
SetImageLoaders(aFrame, BACKGROUND_IMAGE, loader);
|
loaders = nsImageLoader::Create(aFrame, image, PR_FALSE, loaders);
|
||||||
|
}
|
||||||
|
SetImageLoaders(aFrame, BACKGROUND_IMAGE, loaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -242,21 +242,16 @@
|
||||||
#define NS_COLOR_MOZ_ACTIVEHYPERLINKTEXT -3
|
#define NS_COLOR_MOZ_ACTIVEHYPERLINKTEXT -3
|
||||||
#define NS_COLOR_CURRENTCOLOR -4
|
#define NS_COLOR_CURRENTCOLOR -4
|
||||||
|
|
||||||
// See nsStyleBackground
|
|
||||||
// 0x01 was background-color:transparent
|
|
||||||
#define NS_STYLE_BG_IMAGE_NONE 0x02
|
|
||||||
#define NS_STYLE_BG_X_POSITION_PERCENT 0x04
|
|
||||||
#define NS_STYLE_BG_X_POSITION_LENGTH 0x08
|
|
||||||
#define NS_STYLE_BG_Y_POSITION_PERCENT 0x10
|
|
||||||
#define NS_STYLE_BG_Y_POSITION_LENGTH 0x20
|
|
||||||
|
|
||||||
// See nsStyleBackground
|
// See nsStyleBackground
|
||||||
#define NS_STYLE_BG_ATTACHMENT_SCROLL 0
|
#define NS_STYLE_BG_ATTACHMENT_SCROLL 0
|
||||||
#define NS_STYLE_BG_ATTACHMENT_FIXED 1
|
#define NS_STYLE_BG_ATTACHMENT_FIXED 1
|
||||||
|
|
||||||
// See nsStyleBackground
|
// See nsStyleBackground
|
||||||
|
// Code depends on these constants having the same values as BG_ORIGIN_*
|
||||||
#define NS_STYLE_BG_CLIP_BORDER 0
|
#define NS_STYLE_BG_CLIP_BORDER 0
|
||||||
#define NS_STYLE_BG_CLIP_PADDING 1
|
#define NS_STYLE_BG_CLIP_PADDING 1
|
||||||
|
// When we add NS_STYLE_BG_CLIP_CONTENT, we should add the PR_STATIC_ASSERTs
|
||||||
|
// to the places that assert equality for BORDER and PADDING.
|
||||||
|
|
||||||
// See nsStyleBackground
|
// See nsStyleBackground
|
||||||
#define NS_STYLE_BG_INLINE_POLICY_EACH_BOX 0
|
#define NS_STYLE_BG_INLINE_POLICY_EACH_BOX 0
|
||||||
|
@ -264,6 +259,7 @@
|
||||||
#define NS_STYLE_BG_INLINE_POLICY_BOUNDING_BOX 2
|
#define NS_STYLE_BG_INLINE_POLICY_BOUNDING_BOX 2
|
||||||
|
|
||||||
// See nsStyleBackground
|
// See nsStyleBackground
|
||||||
|
// Code depends on these constants having the same values as BG_CLIP_*
|
||||||
#define NS_STYLE_BG_ORIGIN_BORDER 0
|
#define NS_STYLE_BG_ORIGIN_BORDER 0
|
||||||
#define NS_STYLE_BG_ORIGIN_PADDING 1
|
#define NS_STYLE_BG_ORIGIN_PADDING 1
|
||||||
#define NS_STYLE_BG_ORIGIN_CONTENT 2
|
#define NS_STYLE_BG_ORIGIN_CONTENT 2
|
||||||
|
|
|
@ -547,14 +547,18 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||||
// to clear those notifiers unless we have to. (They'll be reset
|
// to clear those notifiers unless we have to. (They'll be reset
|
||||||
// when we paint, although we could miss a notification in that
|
// when we paint, although we could miss a notification in that
|
||||||
// interval.)
|
// interval.)
|
||||||
imgIRequest *oldBackgroundImage =
|
const nsStyleBackground *oldBG = aOldStyleContext->GetStyleBackground();
|
||||||
aOldStyleContext->GetStyleBackground()->mBackgroundImage;
|
const nsStyleBackground *newBG = GetStyleBackground();
|
||||||
if (oldBackgroundImage &&
|
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, oldBG) {
|
||||||
!EqualImages(oldBackgroundImage,
|
imgIRequest *oldImage = oldBG->mLayers[i].mImage.mRequest;
|
||||||
GetStyleBackground()->mBackgroundImage)) {
|
imgIRequest *newImage =
|
||||||
// stop the image loading for the frame, the image has changed
|
(i < newBG->mImageCount) ? newBG->mLayers[i].mImage.mRequest : nsnull;
|
||||||
PresContext()->SetImageLoaders(this,
|
if (oldImage && !EqualImages(oldImage, newImage)) {
|
||||||
nsPresContext::BACKGROUND_IMAGE, nsnull);
|
// stop the image loading for the frame, the image has changed
|
||||||
|
PresContext()->SetImageLoaders(this,
|
||||||
|
nsPresContext::BACKGROUND_IMAGE, nsnull);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4028,11 +4032,14 @@ nsIFrame::CheckInvalidateSizeChange(const nsRect& aOldRect,
|
||||||
|
|
||||||
// Invalidate the old frame background if the frame has a background
|
// Invalidate the old frame background if the frame has a background
|
||||||
// whose position depends on the size of the frame
|
// whose position depends on the size of the frame
|
||||||
const nsStyleBackground* background = GetStyleBackground();
|
const nsStyleBackground *bg = GetStyleBackground();
|
||||||
if (background->mBackgroundFlags &
|
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
|
||||||
(NS_STYLE_BG_X_POSITION_PERCENT | NS_STYLE_BG_Y_POSITION_PERCENT)) {
|
const nsStyleBackground::Layer &layer = bg->mLayers[i];
|
||||||
Invalidate(nsRect(0, 0, aOldRect.width, aOldRect.height));
|
if (layer.mImage.mRequest &&
|
||||||
return;
|
(layer.mPosition.mXIsPercent || layer.mPosition.mYIsPercent)) {
|
||||||
|
Invalidate(nsRect(0, 0, aOldRect.width, aOldRect.height));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
После Ширина: | Высота: | Размер: 110 B |
После Ширина: | Высота: | Размер: 110 B |
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: fallback colors</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<meta name="assert" content="Fallback color only applied when there is an image." />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: lime red;
|
||||||
|
}
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: fallback colors</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<meta name="assert" content="Fallback color only applied when there is an image." />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background-color: lime red;
|
||||||
|
}
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: fallback colors</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<meta name="assert" content="Fallback color not applied when background image loads successfully." />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: url(transparent-32x32.png) lime red;
|
||||||
|
}
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: fallback colors</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<meta name="assert" content="Fallback color applied when background image corrupted." />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: url(malformed.png) red lime;
|
||||||
|
}
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: fallback colors</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<meta name="assert" content="Fallback color applied when background image missing." />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: url(404.png) red lime;
|
||||||
|
}
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: fallback colors</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<meta name="assert" content="Fallback color is based on whether the *bottom-most* image is corrupted." />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: url(transparent-32x32.png), url(malformed.png) red lime;
|
||||||
|
}
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: fallback colors</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<meta name="assert" content="Fallback color is based on whether the *bottom-most* image is corrupted." />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: url(malformed.png), url(transparent-32x32.png) lime red;
|
||||||
|
}
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: fallback colors</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<meta name="assert" content="Fallback color is based on whether the *bottom-most* image is missing." />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: url(transparent-32x32.png), url(404.png) red lime;
|
||||||
|
}
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: fallback colors</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<meta name="assert" content="Fallback color is based on whether the *bottom-most* image is missing." />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: url(404.png), url(transparent-32x32.png) lime red;
|
||||||
|
}
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: fallback colors</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: url(lime-32x32.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
После Ширина: | Высота: | Размер: 110 B |
|
@ -0,0 +1,35 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: number of background layers determined by background-image</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#layering" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div {
|
||||||
|
position: relative; height: 100px; width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<img style="position: absolute; left: 10px; top: 10px" src="aqua-32x32.png" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img style="position: absolute; left: 15px; top: 15px" src="fuchsia-32x32.png" />
|
||||||
|
<img style="position: absolute; left: 20px; top: 20px" src="blue-32x32.png" />
|
||||||
|
<img style="position: absolute; left: 5px; top: 5px" src="aqua-32x32.png" />
|
||||||
|
<img style="position: absolute; left: 10px; top: 10px" src="yellow-32x32.png" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img style="position: absolute; left: 20px; top: 20px" src="fuchsia-32x32.png" />
|
||||||
|
<img style="position: absolute; left: 5px; top: 5px" src="yellow-32x32.png" />
|
||||||
|
<img style="position: absolute; left: 10px; top: 10px" src="blue-32x32.png" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,35 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: number of background layers determined by background-image</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#layering" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div {
|
||||||
|
position: relative; height: 100px; width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<img style="position: absolute; left: 10px; top: 10px" src="yellow-32x32.png" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img style="position: absolute; left: 15px; top: 15px" src="fuchsia-32x32.png" />
|
||||||
|
<img style="position: absolute; left: 20px; top: 20px" src="blue-32x32.png" />
|
||||||
|
<img style="position: absolute; left: 0px; top: 0px" src="aqua-32x32.png" />
|
||||||
|
<img style="position: absolute; left: 5px; top: 5px" src="yellow-32x32.png" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img style="position: absolute; left: 20px; top: 20px" src="blue-32x32.png" />
|
||||||
|
<img style="position: absolute; left: 5px; top: 5px" src="aqua-32x32.png" />
|
||||||
|
<img style="position: absolute; left: 10px; top: 10px" src="yellow-32x32.png" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: number of background layers determined by background-image</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#layering" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div {
|
||||||
|
position: relative; height: 100px; width: 100px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 10px 10px, 5px 5px, 20px 20px, 15px 15px;
|
||||||
|
background-image: url(aqua-32x32.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.withclass {
|
||||||
|
background-image: url(yellow-32x32.png), url(aqua-32x32.png), url(blue-32x32.png), url(fuchsia-32x32.png), url(red-32x32.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
div#withid {
|
||||||
|
background-image: url(blue-32x32.png), url(yellow-32x32.png), url(fuchsia-32x32.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div></div>
|
||||||
|
<div class="withclass"></div>
|
||||||
|
<div class="withclass" id="withid"></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: number of background layers determined by background-image</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#layering" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div {
|
||||||
|
position: relative; height: 100px; width: 100px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 10px 10px;
|
||||||
|
background-image: url(yellow-32x32.png), url(aqua-32x32.png), url(blue-32x32.png), url(fuchsia-32x32.png), url(red-32x32.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.withclass {
|
||||||
|
background-position: 5px 5px, 0px 0px, 20px 20px, 15px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#withid {
|
||||||
|
background-position: 10px 10px, 5px 5px, 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div></div>
|
||||||
|
<div class="withclass"></div>
|
||||||
|
<div class="withclass" id="withid"></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,39 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: number of background layers determined by background-image</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#layering" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
body > div {
|
||||||
|
position: relative; height: 300px; width: 100px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 10px 10px, 5px 5px, 20px 20px, 15px 15px;
|
||||||
|
background-image: url(aqua-32x32.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
body > div > div {
|
||||||
|
position: absolute; height: 200px; width: 100px; top: 100px; left: 0;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: inherit;
|
||||||
|
background-image: url(yellow-32x32.png), url(aqua-32x32.png), url(blue-32x32.png), url(fuchsia-32x32.png), url(red-32x32.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
body > div > div > div {
|
||||||
|
position: absolute; height: 100px; width: 100px; top: 100px; left: 0;
|
||||||
|
background: inherit;
|
||||||
|
background-image: url(blue-32x32.png), url(yellow-32x32.png), url(fuchsia-32x32.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div><div><div></div></div></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,39 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: number of background layers determined by background-image</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#layering" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
body > div {
|
||||||
|
position: relative; height: 300px; width: 100px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 10px 10px;
|
||||||
|
background-image: url(yellow-32x32.png), url(aqua-32x32.png), url(blue-32x32.png), url(fuchsia-32x32.png), url(red-32x32.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
body > div > div {
|
||||||
|
position: absolute; height: 200px; width: 100px; top: 100px; left: 0;
|
||||||
|
background: inherit;
|
||||||
|
background-position: 5px 5px, 0px 0px, 20px 20px, 15px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body > div > div > div {
|
||||||
|
position: absolute; height: 100px; width: 100px; top: 100px; left: 0;
|
||||||
|
background-image: inherit;
|
||||||
|
background-repeat: inherit;
|
||||||
|
background-position: 10px 10px, 5px 5px, 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div><div><div></div></div></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: stacking order of layers</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#layering" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div#test {
|
||||||
|
position: relative; height: 100px; width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="test">
|
||||||
|
<img src="aqua-32x32.png" style="position: absolute; left: 20px; top: 20px" />
|
||||||
|
<img src="fuchsia-32x32.png" style="position: absolute; left: 10px; top: 10px" />
|
||||||
|
<img src="yellow-32x32.png" style="position: absolute; left: 15px; top: 15px" />
|
||||||
|
<img src="blue-32x32.png" style="position: absolute; left: 5px; top: 5px" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,27 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>css3-background: stacking order of layers</title>
|
||||||
|
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
|
||||||
|
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||||
|
<link rel="help" href="http://dev.w3.org/csswg/css3-background/#layering" />
|
||||||
|
<meta name="flags" content="" />
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
|
||||||
|
div#test {
|
||||||
|
position: relative; height: 100px; width: 100px;
|
||||||
|
background: url(blue-32x32.png) 5px 5px no-repeat,
|
||||||
|
url(yellow-32x32.png) 15px 15px no-repeat,
|
||||||
|
url(fuchsia-32x32.png) 10px 10px no-repeat,
|
||||||
|
url(aqua-32x32.png) 20px 20px no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="test"></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
После Ширина: | Высота: | Размер: 110 B |
|
@ -0,0 +1 @@
|
||||||
|
This is not a PNG file.
|
После Ширина: | Высота: | Размер: 110 B |
|
@ -0,0 +1,15 @@
|
||||||
|
== fallback-color-1.xhtml fallback-color-ref.xhtml
|
||||||
|
== fallback-color-2.xhtml fallback-color-ref.xhtml
|
||||||
|
== fallback-color-3.xhtml fallback-color-ref.xhtml
|
||||||
|
== fallback-color-4.xhtml fallback-color-ref.xhtml
|
||||||
|
== fallback-color-5.xhtml fallback-color-ref.xhtml
|
||||||
|
== fallback-color-6.xhtml fallback-color-ref.xhtml
|
||||||
|
== fallback-color-7.xhtml fallback-color-ref.xhtml
|
||||||
|
== fallback-color-8.xhtml fallback-color-ref.xhtml
|
||||||
|
== fallback-color-9.xhtml fallback-color-ref.xhtml
|
||||||
|
!= fallback-color-ref.xhtml about:blank
|
||||||
|
== layers-stacking-order.xhtml layers-stacking-order-ref.xhtml
|
||||||
|
== layers-layer-count-cascade-1.xhtml layers-layer-count-1-ref.xhtml
|
||||||
|
== layers-layer-count-inheritance-1.xhtml layers-layer-count-1-ref.xhtml
|
||||||
|
== layers-layer-count-cascade-2.xhtml layers-layer-count-2-ref.xhtml
|
||||||
|
== layers-layer-count-inheritance-2.xhtml layers-layer-count-2-ref.xhtml
|
После Ширина: | Высота: | Размер: 96 B |
После Ширина: | Высота: | Размер: 110 B |
|
@ -98,7 +98,7 @@
|
||||||
.parser { height: 3em; }
|
.parser { height: 3em; }
|
||||||
.parser { width: 200; }
|
.parser { width: 200; }
|
||||||
.parser { border: 5em solid red ! error; }
|
.parser { border: 5em solid red ! error; }
|
||||||
.parser { background: red pink; }
|
.parser { background: red pink pink; }
|
||||||
|
|
||||||
/* line fourteen (last line of face): table */
|
/* line fourteen (last line of face): table */
|
||||||
ul { display: table; padding: 0; margin: -1em 7em 0; background: red; }
|
ul { display: table; padding: 0; margin: -1em 7em 0; background: red; }
|
||||||
|
|
|
@ -11,6 +11,9 @@ include reftest-sanity/reftest.list
|
||||||
# images (if libpr0n is busted, could result in weird failures in other tests)
|
# images (if libpr0n is busted, could result in weird failures in other tests)
|
||||||
include ../../modules/libpr0n/test/reftest/reftest.list
|
include ../../modules/libpr0n/test/reftest/reftest.list
|
||||||
|
|
||||||
|
# backgrounds/
|
||||||
|
include backgrounds/reftest.list
|
||||||
|
|
||||||
# bidi/
|
# bidi/
|
||||||
include bidi/reftest.list
|
include bidi/reftest.list
|
||||||
|
|
||||||
|
|
|
@ -196,8 +196,7 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
|
||||||
if (target->GetUnit() == eCSSUnit_Null) {
|
if (target->GetUnit() == eCSSUnit_Null) {
|
||||||
const nsCSSValue *val = ValueAtCursor(cursor);
|
const nsCSSValue *val = ValueAtCursor(cursor);
|
||||||
NS_ASSERTION(val->GetUnit() != eCSSUnit_Null, "oops");
|
NS_ASSERTION(val->GetUnit() != eCSSUnit_Null, "oops");
|
||||||
if (iProp == eCSSProperty_background_image ||
|
if (iProp == eCSSProperty_list_style_image) {
|
||||||
iProp == eCSSProperty_list_style_image) {
|
|
||||||
if (val->GetUnit() == eCSSUnit_URL) {
|
if (val->GetUnit() == eCSSUnit_URL) {
|
||||||
val->StartImageLoad(
|
val->StartImageLoad(
|
||||||
aRuleData->mPresContext->Document());
|
aRuleData->mPresContext->Document());
|
||||||
|
@ -217,8 +216,6 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
|
||||||
aRuleData->mFontData->mFamilyFromHTML = PR_FALSE;
|
aRuleData->mFontData->mFamilyFromHTML = PR_FALSE;
|
||||||
}
|
}
|
||||||
else if (iProp == eCSSProperty_color ||
|
else if (iProp == eCSSProperty_color ||
|
||||||
iProp == eCSSProperty_background_color ||
|
|
||||||
iProp == eCSSProperty_background_image ||
|
|
||||||
iProp == eCSSProperty_border_top_color ||
|
iProp == eCSSProperty_border_top_color ||
|
||||||
iProp == eCSSProperty_border_right_color_value ||
|
iProp == eCSSProperty_border_right_color_value ||
|
||||||
iProp == eCSSProperty_border_right_color_ltr_source ||
|
iProp == eCSSProperty_border_right_color_ltr_source ||
|
||||||
|
@ -230,32 +227,8 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
|
||||||
iProp == eCSSProperty__moz_column_rule_color ||
|
iProp == eCSSProperty__moz_column_rule_color ||
|
||||||
iProp == eCSSProperty_outline_color) {
|
iProp == eCSSProperty_outline_color) {
|
||||||
if (ShouldIgnoreColors(aRuleData)) {
|
if (ShouldIgnoreColors(aRuleData)) {
|
||||||
if (iProp == eCSSProperty_background_color) {
|
// Ignore 'color', 'border-*-color', etc.
|
||||||
// Force non-'transparent' background
|
*target = nsCSSValue();
|
||||||
// colors to the user's default.
|
|
||||||
// We have the value in the form it was
|
|
||||||
// specified at this point, so we have to
|
|
||||||
// look for both the keyword 'transparent'
|
|
||||||
// and its equivalent in rgba notation.
|
|
||||||
nsCSSUnit u = target->GetUnit();
|
|
||||||
nsDependentString buf;
|
|
||||||
|
|
||||||
if ((u == eCSSUnit_Color &&
|
|
||||||
NS_GET_A(target->GetColorValue())
|
|
||||||
> 0) ||
|
|
||||||
(u == eCSSUnit_String &&
|
|
||||||
!nsGkAtoms::transparent->
|
|
||||||
Equals(target->GetStringValue(buf))) ||
|
|
||||||
(u == eCSSUnit_EnumColor)) {
|
|
||||||
target->SetColorValue(aRuleData->
|
|
||||||
mPresContext->
|
|
||||||
DefaultBackgroundColor());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Ignore 'color', 'border-*-color', and
|
|
||||||
// 'background-image'
|
|
||||||
*target = nsCSSValue();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,15 +255,50 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
|
||||||
NS_ASSERTION(val->mXValue.GetUnit() != eCSSUnit_Null ||
|
NS_ASSERTION(val->mXValue.GetUnit() != eCSSUnit_Null ||
|
||||||
val->mYValue.GetUnit() != eCSSUnit_Null, "oops");
|
val->mYValue.GetUnit() != eCSSUnit_Null, "oops");
|
||||||
nsCSSValuePair* target = static_cast<nsCSSValuePair*>(prop);
|
nsCSSValuePair* target = static_cast<nsCSSValuePair*>(prop);
|
||||||
if (target->mXValue.GetUnit() == eCSSUnit_Null)
|
NS_ASSERTION((target->mXValue.GetUnit() == eCSSUnit_Null)
|
||||||
|
== (target->mYValue.GetUnit() == eCSSUnit_Null),
|
||||||
|
"half a property?");
|
||||||
|
if (target->mXValue.GetUnit() == eCSSUnit_Null) {
|
||||||
target->mXValue = val->mXValue;
|
target->mXValue = val->mXValue;
|
||||||
if (target->mYValue.GetUnit() == eCSSUnit_Null)
|
|
||||||
target->mYValue = val->mYValue;
|
target->mYValue = val->mYValue;
|
||||||
|
if (iProp == eCSSProperty_background_color &&
|
||||||
|
ShouldIgnoreColors(aRuleData)) {
|
||||||
|
// Force non-'transparent' background colors
|
||||||
|
// to the user's default. We have the value
|
||||||
|
// in the form it was specified at this
|
||||||
|
// point, so we have to look for both the
|
||||||
|
// keyword 'transparent' and its equivalent
|
||||||
|
// in rgba notation.
|
||||||
|
nsCSSValue &colorVal = target->mXValue;
|
||||||
|
nsCSSUnit u = colorVal.GetUnit();
|
||||||
|
nsDependentString buf;
|
||||||
|
|
||||||
|
if ((u == eCSSUnit_Color &&
|
||||||
|
NS_GET_A(colorVal.GetColorValue())
|
||||||
|
> 0) ||
|
||||||
|
(u == eCSSUnit_String &&
|
||||||
|
!nsGkAtoms::transparent->
|
||||||
|
Equals(colorVal.GetStringValue(buf))) ||
|
||||||
|
(u == eCSSUnit_EnumColor)) {
|
||||||
|
colorVal.SetColorValue(aRuleData->
|
||||||
|
mPresContext->
|
||||||
|
DefaultBackgroundColor());
|
||||||
|
}
|
||||||
|
// We could consider using the fallback
|
||||||
|
// background color for both values, but it
|
||||||
|
// might not make sense if the author didn't
|
||||||
|
// specify an image. But since we're
|
||||||
|
// dropping author images, we'll just use
|
||||||
|
// the non-fallback for both.
|
||||||
|
target->mYValue = target->mXValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
cursor += CDBValuePairStorage_advance;
|
cursor += CDBValuePairStorage_advance;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case eCSSType_ValueList:
|
case eCSSType_ValueList:
|
||||||
if (iProp == eCSSProperty_content) {
|
if (iProp == eCSSProperty_background_image ||
|
||||||
|
iProp == eCSSProperty_content) {
|
||||||
for (nsCSSValueList* l = ValueListAtCursor(cursor);
|
for (nsCSSValueList* l = ValueListAtCursor(cursor);
|
||||||
l; l = l->mNext)
|
l; l = l->mNext)
|
||||||
if (l->mValue.GetUnit() == eCSSUnit_URL)
|
if (l->mValue.GetUnit() == eCSSUnit_URL)
|
||||||
|
@ -317,7 +325,8 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
|
||||||
NS_ASSERTION(val, "oops");
|
NS_ASSERTION(val, "oops");
|
||||||
*target = val;
|
*target = val;
|
||||||
|
|
||||||
if (iProp == eCSSProperty_border_top_colors ||
|
if (iProp == eCSSProperty_background_image ||
|
||||||
|
iProp == eCSSProperty_border_top_colors ||
|
||||||
iProp == eCSSProperty_border_right_colors ||
|
iProp == eCSSProperty_border_right_colors ||
|
||||||
iProp == eCSSProperty_border_bottom_colors ||
|
iProp == eCSSProperty_border_bottom_colors ||
|
||||||
iProp == eCSSProperty_border_left_colors) {
|
iProp == eCSSProperty_border_left_colors) {
|
||||||
|
|
|
@ -209,12 +209,17 @@ PRBool nsCSSDeclaration::AppendValueToString(nsCSSProperty aProperty, nsAString&
|
||||||
NS_ASSERTION(item->mXValue.GetUnit() != eCSSUnit_Null,
|
NS_ASSERTION(item->mXValue.GetUnit() != eCSSUnit_Null,
|
||||||
"unexpected null unit");
|
"unexpected null unit");
|
||||||
AppendCSSValueToString(aProperty, item->mXValue, aResult);
|
AppendCSSValueToString(aProperty, item->mXValue, aResult);
|
||||||
if (item->mYValue.GetUnit() != eCSSUnit_Null) {
|
if (item->mXValue.GetUnit() != eCSSUnit_Inherit &&
|
||||||
|
item->mXValue.GetUnit() != eCSSUnit_Initial &&
|
||||||
|
item->mYValue.GetUnit() != eCSSUnit_Null) {
|
||||||
aResult.Append(PRUnichar(' '));
|
aResult.Append(PRUnichar(' '));
|
||||||
AppendCSSValueToString(aProperty, item->mYValue, aResult);
|
AppendCSSValueToString(aProperty, item->mYValue, aResult);
|
||||||
}
|
}
|
||||||
item = item->mNext;
|
item = item->mNext;
|
||||||
if (item) {
|
if (item) {
|
||||||
|
if (nsCSSProps::PropHasFlags(aProperty,
|
||||||
|
CSS_PROPERTY_VALUE_LIST_USES_COMMAS))
|
||||||
|
aResult.Append(PRUnichar(','));
|
||||||
aResult.Append(PRUnichar(' '));
|
aResult.Append(PRUnichar(' '));
|
||||||
}
|
}
|
||||||
} while (item);
|
} while (item);
|
||||||
|
@ -761,50 +766,97 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case eCSSProperty_background: {
|
case eCSSProperty_background: {
|
||||||
// The -moz-background-clip, -moz-background-origin, and
|
// We know from above that all subproperties were specified.
|
||||||
// -moz-background-inline-policy properties are reset by this
|
// However, we still can't represent that in the shorthand unless
|
||||||
// shorthand property to their initial values, but can't be
|
// they're all lists of the same length. So if they're different
|
||||||
// represented in its syntax.
|
// lengths, we need to bail out.
|
||||||
const nsCSSValue *clipValue = static_cast<const nsCSSValue*>(
|
// We also need to bail out if an item has background-clip and
|
||||||
data->StorageFor(eCSSProperty__moz_background_clip));
|
// background-origin that are different and not the default
|
||||||
const nsCSSValue *originValue = static_cast<const nsCSSValue*>(
|
// values. (We omit them if they're both default.)
|
||||||
data->StorageFor(eCSSProperty__moz_background_origin));
|
const nsCSSValueList *image =
|
||||||
const nsCSSValue *inlinePolicyValue = static_cast<const nsCSSValue*>(
|
* data->ValueListStorageFor(eCSSProperty_background_image);
|
||||||
data->StorageFor(eCSSProperty__moz_background_inline_policy));
|
const nsCSSValueList *repeat =
|
||||||
if (*clipValue !=
|
* data->ValueListStorageFor(eCSSProperty_background_repeat);
|
||||||
nsCSSValue(NS_STYLE_BG_CLIP_BORDER, eCSSUnit_Enumerated) ||
|
const nsCSSValueList *attachment =
|
||||||
*originValue !=
|
* data->ValueListStorageFor(eCSSProperty_background_attachment);
|
||||||
nsCSSValue(NS_STYLE_BG_ORIGIN_PADDING, eCSSUnit_Enumerated) ||
|
const nsCSSValuePairList *position =
|
||||||
*inlinePolicyValue !=
|
* data->ValuePairListStorageFor(eCSSProperty_background_position);
|
||||||
nsCSSValue(NS_STYLE_BG_INLINE_POLICY_CONTINUOUS,
|
const nsCSSValueList *clip =
|
||||||
eCSSUnit_Enumerated)) {
|
* data->ValueListStorageFor(eCSSProperty__moz_background_clip);
|
||||||
return NS_OK;
|
const nsCSSValueList *origin =
|
||||||
}
|
* data->ValueListStorageFor(eCSSProperty__moz_background_origin);
|
||||||
|
for (;;) {
|
||||||
PRBool appendedSomething = PR_FALSE;
|
AppendCSSValueToString(eCSSProperty_background_image,
|
||||||
if (AppendValueToString(eCSSProperty_background_color, aValue)) {
|
image->mValue, aValue);
|
||||||
appendedSomething = PR_TRUE;
|
aValue.Append(PRUnichar(' '));
|
||||||
|
AppendCSSValueToString(eCSSProperty_background_repeat,
|
||||||
|
repeat->mValue, aValue);
|
||||||
|
aValue.Append(PRUnichar(' '));
|
||||||
|
AppendCSSValueToString(eCSSProperty_background_attachment,
|
||||||
|
attachment->mValue, aValue);
|
||||||
|
aValue.Append(PRUnichar(' '));
|
||||||
|
AppendCSSValueToString(eCSSProperty_background_position,
|
||||||
|
position->mXValue, aValue);
|
||||||
|
aValue.Append(PRUnichar(' '));
|
||||||
|
AppendCSSValueToString(eCSSProperty_background_position,
|
||||||
|
position->mYValue, aValue);
|
||||||
|
NS_ASSERTION(clip->mValue.GetUnit() == eCSSUnit_Enumerated &&
|
||||||
|
origin->mValue.GetUnit() == eCSSUnit_Enumerated,
|
||||||
|
"should not be inherit/initial within list and "
|
||||||
|
"should have returned early for real inherit/initial");
|
||||||
|
if (clip->mValue.GetIntValue() != NS_STYLE_BG_CLIP_BORDER ||
|
||||||
|
origin->mValue.GetIntValue() != NS_STYLE_BG_ORIGIN_PADDING) {
|
||||||
|
#if 0
|
||||||
|
// This is commented out for now until we change
|
||||||
|
// -moz-background-clip to background-clip, -moz-background-origin
|
||||||
|
// to background-origin, change their value names to *-box, and add
|
||||||
|
// support for content-box on background-clip.
|
||||||
|
PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_BORDER ==
|
||||||
|
NS_STYLE_BG_ORIGIN_BORDER);
|
||||||
|
PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_PADDING ==
|
||||||
|
NS_STYLE_BG_ORIGIN_PADDING);
|
||||||
|
// PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_CONTENT == /* does not exist */
|
||||||
|
// NS_STYLE_BG_ORIGIN_CONTENT);
|
||||||
|
if (clip->mValue != origin->mValue) {
|
||||||
|
aValue.Truncate();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
aValue.Append(PRUnichar(' '));
|
||||||
|
AppendCSSValueToString(eCSSProperty__moz_background_clip,
|
||||||
|
clip->mValue, aValue);
|
||||||
|
#else
|
||||||
|
aValue.Truncate();
|
||||||
|
return NS_OK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
image = image->mNext;
|
||||||
|
repeat = repeat->mNext;
|
||||||
|
attachment = attachment->mNext;
|
||||||
|
position = position->mNext;
|
||||||
|
clip = clip->mNext;
|
||||||
|
origin = origin->mNext;
|
||||||
|
|
||||||
|
if (!image) {
|
||||||
|
if (repeat || attachment || position || clip || origin) {
|
||||||
|
// Uneven length lists, so can't be serialized as shorthand.
|
||||||
|
aValue.Truncate();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!repeat || !attachment || !position || !clip || !origin) {
|
||||||
|
// Uneven length lists, so can't be serialized as shorthand.
|
||||||
|
aValue.Truncate();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
aValue.Append(PRUnichar(','));
|
||||||
aValue.Append(PRUnichar(' '));
|
aValue.Append(PRUnichar(' '));
|
||||||
}
|
}
|
||||||
if (AppendValueToString(eCSSProperty_background_image, aValue)) {
|
|
||||||
aValue.Append(PRUnichar(' '));
|
aValue.Append(PRUnichar(' '));
|
||||||
appendedSomething = PR_TRUE;
|
AppendValueToString(eCSSProperty_background_color, aValue);
|
||||||
}
|
|
||||||
if (AppendValueToString(eCSSProperty_background_repeat, aValue)) {
|
|
||||||
aValue.Append(PRUnichar(' '));
|
|
||||||
appendedSomething = PR_TRUE;
|
|
||||||
}
|
|
||||||
if (AppendValueToString(eCSSProperty_background_attachment, aValue)) {
|
|
||||||
aValue.Append(PRUnichar(' '));
|
|
||||||
appendedSomething = PR_TRUE;
|
|
||||||
}
|
|
||||||
if (!AppendValueToString(eCSSProperty_background_position, aValue) &&
|
|
||||||
appendedSomething) {
|
|
||||||
NS_ASSERTION(!aValue.IsEmpty() && aValue.Last() == PRUnichar(' '),
|
|
||||||
"We appended a space before!");
|
|
||||||
// We appended an extra space. Let's get rid of it
|
|
||||||
aValue.Truncate(aValue.Length() - 1);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case eCSSProperty_cue: {
|
case eCSSProperty_cue: {
|
||||||
|
|
|
@ -84,6 +84,7 @@
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
|
#include "prlog.h"
|
||||||
|
|
||||||
// Flags for ParseVariant method
|
// Flags for ParseVariant method
|
||||||
#define VARIANT_KEYWORD 0x000001 // K
|
#define VARIANT_KEYWORD 0x000001 // K
|
||||||
|
@ -390,9 +391,30 @@ protected:
|
||||||
// Property specific parsing routines
|
// Property specific parsing routines
|
||||||
PRBool ParseAzimuth(nsCSSValue& aValue);
|
PRBool ParseAzimuth(nsCSSValue& aValue);
|
||||||
PRBool ParseBackground();
|
PRBool ParseBackground();
|
||||||
|
|
||||||
|
struct BackgroundItem;
|
||||||
|
friend struct BackgroundItem;
|
||||||
|
struct BackgroundItem {
|
||||||
|
nsCSSValue mImage;
|
||||||
|
nsCSSValue mRepeat;
|
||||||
|
nsCSSValue mAttachment;
|
||||||
|
nsCSSValuePair mPosition;
|
||||||
|
nsCSSValue mClip;
|
||||||
|
nsCSSValue mOrigin;
|
||||||
|
// The background-color is set as a side-effect, and if so, mLastItem
|
||||||
|
// is set to true.
|
||||||
|
PRBool mLastItem;
|
||||||
|
};
|
||||||
|
struct BackgroundItemSimpleValueInfo {
|
||||||
|
nsCSSValue BackgroundItem::*member;
|
||||||
|
nsCSSProperty propID;
|
||||||
|
};
|
||||||
|
|
||||||
|
PRBool ParseBackgroundItem(BackgroundItem& aItem, PRBool aFirstItem);
|
||||||
|
|
||||||
|
PRBool ParseBackgroundList(nsCSSProperty aPropID); // a single value prop-id
|
||||||
|
PRBool ParseBackgroundColor(PRBool aInShorthand);
|
||||||
PRBool ParseBackgroundPosition();
|
PRBool ParseBackgroundPosition();
|
||||||
PRBool ParseBackgroundPositionValues();
|
|
||||||
PRBool ParseBoxPosition(nsCSSValuePair& aOut);
|
|
||||||
PRBool ParseBoxPositionValues(nsCSSValuePair& aOut);
|
PRBool ParseBoxPositionValues(nsCSSValuePair& aOut);
|
||||||
PRBool ParseBorderColor();
|
PRBool ParseBorderColor();
|
||||||
PRBool ParseBorderColors(nsCSSValueList** aResult,
|
PRBool ParseBorderColors(nsCSSValueList** aResult,
|
||||||
|
@ -4940,8 +4962,16 @@ CSSParserImpl::ParseProperty(nsCSSProperty aPropID)
|
||||||
switch (aPropID) { // handle shorthand or multiple properties
|
switch (aPropID) { // handle shorthand or multiple properties
|
||||||
case eCSSProperty_background:
|
case eCSSProperty_background:
|
||||||
return ParseBackground();
|
return ParseBackground();
|
||||||
|
case eCSSProperty_background_color:
|
||||||
|
return ParseBackgroundColor(PR_FALSE);
|
||||||
case eCSSProperty_background_position:
|
case eCSSProperty_background_position:
|
||||||
return ParseBackgroundPosition();
|
return ParseBackgroundPosition();
|
||||||
|
case eCSSProperty_background_attachment:
|
||||||
|
case eCSSProperty__moz_background_clip:
|
||||||
|
case eCSSProperty_background_image:
|
||||||
|
case eCSSProperty__moz_background_origin:
|
||||||
|
case eCSSProperty_background_repeat:
|
||||||
|
return ParseBackgroundList(aPropID);
|
||||||
case eCSSProperty_border:
|
case eCSSProperty_border:
|
||||||
return ParseBorderSide(kBorderTopIDs, PR_TRUE);
|
return ParseBorderSide(kBorderTopIDs, PR_TRUE);
|
||||||
case eCSSProperty_border_color:
|
case eCSSProperty_border_color:
|
||||||
|
@ -5193,6 +5223,7 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
|
||||||
switch (aPropID) {
|
switch (aPropID) {
|
||||||
case eCSSProperty_UNKNOWN:
|
case eCSSProperty_UNKNOWN:
|
||||||
case eCSSProperty_background:
|
case eCSSProperty_background:
|
||||||
|
case eCSSProperty_background_color:
|
||||||
case eCSSProperty_background_position:
|
case eCSSProperty_background_position:
|
||||||
case eCSSProperty_border:
|
case eCSSProperty_border:
|
||||||
case eCSSProperty_border_color:
|
case eCSSProperty_border_color:
|
||||||
|
@ -5305,22 +5336,25 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
|
||||||
case eCSSProperty_azimuth:
|
case eCSSProperty_azimuth:
|
||||||
return ParseAzimuth(aValue);
|
return ParseAzimuth(aValue);
|
||||||
case eCSSProperty_background_attachment:
|
case eCSSProperty_background_attachment:
|
||||||
|
// Used only internally.
|
||||||
return ParseVariant(aValue, VARIANT_HK,
|
return ParseVariant(aValue, VARIANT_HK,
|
||||||
nsCSSProps::kBackgroundAttachmentKTable);
|
nsCSSProps::kBackgroundAttachmentKTable);
|
||||||
case eCSSProperty__moz_background_clip:
|
case eCSSProperty__moz_background_clip:
|
||||||
|
// Used only internally.
|
||||||
return ParseVariant(aValue, VARIANT_HK,
|
return ParseVariant(aValue, VARIANT_HK,
|
||||||
nsCSSProps::kBackgroundClipKTable);
|
nsCSSProps::kBackgroundClipKTable);
|
||||||
case eCSSProperty_background_color:
|
|
||||||
return ParseVariant(aValue, VARIANT_HC, nsnull);
|
|
||||||
case eCSSProperty_background_image:
|
case eCSSProperty_background_image:
|
||||||
|
// Used only internally.
|
||||||
return ParseVariant(aValue, VARIANT_HUO, nsnull);
|
return ParseVariant(aValue, VARIANT_HUO, nsnull);
|
||||||
case eCSSProperty__moz_background_inline_policy:
|
case eCSSProperty__moz_background_inline_policy:
|
||||||
return ParseVariant(aValue, VARIANT_HK,
|
return ParseVariant(aValue, VARIANT_HK,
|
||||||
nsCSSProps::kBackgroundInlinePolicyKTable);
|
nsCSSProps::kBackgroundInlinePolicyKTable);
|
||||||
case eCSSProperty__moz_background_origin:
|
case eCSSProperty__moz_background_origin:
|
||||||
|
// Used only internally.
|
||||||
return ParseVariant(aValue, VARIANT_HK,
|
return ParseVariant(aValue, VARIANT_HK,
|
||||||
nsCSSProps::kBackgroundOriginKTable);
|
nsCSSProps::kBackgroundOriginKTable);
|
||||||
case eCSSProperty_background_repeat:
|
case eCSSProperty_background_repeat:
|
||||||
|
// Used only internally.
|
||||||
return ParseVariant(aValue, VARIANT_HK,
|
return ParseVariant(aValue, VARIANT_HK,
|
||||||
nsCSSProps::kBackgroundRepeatKTable);
|
nsCSSProps::kBackgroundRepeatKTable);
|
||||||
case eCSSProperty_binding:
|
case eCSSProperty_binding:
|
||||||
|
@ -5858,42 +5892,108 @@ CSSParserImpl::ParseBackground()
|
||||||
{
|
{
|
||||||
nsAutoParseCompoundProperty compound(this);
|
nsAutoParseCompoundProperty compound(this);
|
||||||
|
|
||||||
|
// These two are set through side-effects of ParseBackgroundItem.
|
||||||
|
mTempData.mColor.mBackColor.mXValue.SetColorValue(NS_RGBA(0, 0, 0, 0));
|
||||||
|
mTempData.mColor.mBackColor.mYValue.SetColorValue(NS_RGBA(0, 0, 0, 0));
|
||||||
|
|
||||||
|
BackgroundItem bgitem;
|
||||||
|
nsCSSValuePairList *positionHead = nsnull, **positionTail = &positionHead;
|
||||||
|
static const BackgroundItemSimpleValueInfo simpleValues[] = {
|
||||||
|
{ &BackgroundItem::mImage, eCSSProperty_background_image },
|
||||||
|
{ &BackgroundItem::mRepeat, eCSSProperty_background_repeat },
|
||||||
|
{ &BackgroundItem::mAttachment, eCSSProperty_background_attachment },
|
||||||
|
{ &BackgroundItem::mClip, eCSSProperty__moz_background_clip },
|
||||||
|
{ &BackgroundItem::mOrigin, eCSSProperty__moz_background_origin }
|
||||||
|
};
|
||||||
|
nsCSSValueList *simpleHeads[NS_ARRAY_LENGTH(simpleValues)];
|
||||||
|
nsCSSValueList **simpleTails[NS_ARRAY_LENGTH(simpleValues)];
|
||||||
|
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(simpleValues); ++i) {
|
||||||
|
simpleHeads[i] = nsnull;
|
||||||
|
simpleTails[i] = &simpleHeads[i];
|
||||||
|
}
|
||||||
|
for (;;) {
|
||||||
|
if (!ParseBackgroundItem(bgitem, !positionHead)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nsCSSValuePairList *positionItem = new nsCSSValuePairList;
|
||||||
|
if (!positionItem) {
|
||||||
|
mScanner.SetLowLevelError(NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
positionItem->mXValue = bgitem.mPosition.mXValue;
|
||||||
|
positionItem->mYValue = bgitem.mPosition.mYValue;
|
||||||
|
*positionTail = positionItem;
|
||||||
|
positionTail = &positionItem->mNext;
|
||||||
|
|
||||||
|
PRBool fail = PR_FALSE;
|
||||||
|
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(simpleValues); ++i) {
|
||||||
|
nsCSSValueList *item = new nsCSSValueList;
|
||||||
|
if (!item) {
|
||||||
|
mScanner.SetLowLevelError(NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
fail = PR_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
item->mValue = bgitem.*(simpleValues[i].member);
|
||||||
|
*simpleTails[i] = item;
|
||||||
|
simpleTails[i] = &item->mNext;
|
||||||
|
}
|
||||||
|
if (fail) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bgitem.mLastItem && ExpectSymbol(',', PR_TRUE)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!ExpectEndProperty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mTempData.mColor.mBackPosition = positionHead;
|
||||||
|
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(simpleValues); ++i) {
|
||||||
|
nsCSSValueList **source = static_cast<nsCSSValueList**>(
|
||||||
|
mTempData.PropertyAt(simpleValues[i].propID));
|
||||||
|
*source = simpleHeads[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
mTempData.SetPropertyBit(eCSSProperty_background_color);
|
||||||
|
mTempData.SetPropertyBit(eCSSProperty_background_image);
|
||||||
|
mTempData.SetPropertyBit(eCSSProperty_background_repeat);
|
||||||
|
mTempData.SetPropertyBit(eCSSProperty_background_attachment);
|
||||||
|
mTempData.SetPropertyBit(eCSSProperty_background_position);
|
||||||
|
mTempData.SetPropertyBit(eCSSProperty__moz_background_clip);
|
||||||
|
mTempData.SetPropertyBit(eCSSProperty__moz_background_origin);
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
delete positionHead;
|
||||||
|
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(simpleValues); ++i) {
|
||||||
|
delete simpleHeads[i];
|
||||||
|
}
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse one item of the background shorthand property.
|
||||||
|
PRBool
|
||||||
|
CSSParserImpl::ParseBackgroundItem(CSSParserImpl::BackgroundItem& aItem,
|
||||||
|
PRBool aFirstItem)
|
||||||
|
{
|
||||||
// Fill in the values that the shorthand will set if we don't find
|
// Fill in the values that the shorthand will set if we don't find
|
||||||
// other values.
|
// other values.
|
||||||
mTempData.mColor.mBackColor.SetColorValue(NS_RGBA(0, 0, 0, 0));
|
aItem.mImage.SetNoneValue();
|
||||||
mTempData.SetPropertyBit(eCSSProperty_background_color);
|
aItem.mRepeat.SetIntValue(NS_STYLE_BG_REPEAT_XY, eCSSUnit_Enumerated);
|
||||||
mTempData.mColor.mBackImage.SetNoneValue();
|
aItem.mAttachment.SetIntValue(NS_STYLE_BG_ATTACHMENT_SCROLL,
|
||||||
mTempData.SetPropertyBit(eCSSProperty_background_image);
|
eCSSUnit_Enumerated);
|
||||||
mTempData.mColor.mBackRepeat.SetIntValue(NS_STYLE_BG_REPEAT_XY,
|
aItem.mPosition.mXValue.SetPercentValue(0.0f);
|
||||||
eCSSUnit_Enumerated);
|
aItem.mPosition.mYValue.SetPercentValue(0.0f);
|
||||||
mTempData.SetPropertyBit(eCSSProperty_background_repeat);
|
aItem.mClip.SetIntValue(NS_STYLE_BG_CLIP_BORDER, eCSSUnit_Enumerated);
|
||||||
mTempData.mColor.mBackAttachment.SetIntValue(NS_STYLE_BG_ATTACHMENT_SCROLL,
|
aItem.mOrigin.SetIntValue(NS_STYLE_BG_ORIGIN_PADDING, eCSSUnit_Enumerated);
|
||||||
eCSSUnit_Enumerated);
|
aItem.mLastItem = PR_FALSE;
|
||||||
mTempData.SetPropertyBit(eCSSProperty_background_attachment);
|
|
||||||
mTempData.mColor.mBackPosition.mXValue.SetPercentValue(0.0f);
|
|
||||||
mTempData.mColor.mBackPosition.mYValue.SetPercentValue(0.0f);
|
|
||||||
mTempData.SetPropertyBit(eCSSProperty_background_position);
|
|
||||||
// including the ones that we can't set from the shorthand.
|
|
||||||
mTempData.mColor.mBackClip.SetIntValue(NS_STYLE_BG_CLIP_BORDER,
|
|
||||||
eCSSUnit_Enumerated);
|
|
||||||
mTempData.SetPropertyBit(eCSSProperty__moz_background_clip);
|
|
||||||
mTempData.mColor.mBackOrigin.SetIntValue(NS_STYLE_BG_ORIGIN_PADDING,
|
|
||||||
eCSSUnit_Enumerated);
|
|
||||||
mTempData.SetPropertyBit(eCSSProperty__moz_background_origin);
|
|
||||||
mTempData.mColor.mBackInlinePolicy.SetIntValue(
|
|
||||||
NS_STYLE_BG_INLINE_POLICY_CONTINUOUS, eCSSUnit_Enumerated);
|
|
||||||
mTempData.SetPropertyBit(eCSSProperty__moz_background_inline_policy);
|
|
||||||
|
|
||||||
// XXX If ParseSingleValueProperty were table-driven (bug 376079) and
|
|
||||||
// automatically filled in the right field of mTempData, we could move
|
|
||||||
// ParseBackgroundPosition to it (as a special case) and switch back
|
|
||||||
// to using ParseChoice here.
|
|
||||||
|
|
||||||
PRBool haveColor = PR_FALSE,
|
PRBool haveColor = PR_FALSE,
|
||||||
haveImage = PR_FALSE,
|
haveImage = PR_FALSE,
|
||||||
haveRepeat = PR_FALSE,
|
haveRepeat = PR_FALSE,
|
||||||
haveAttach = PR_FALSE,
|
haveAttach = PR_FALSE,
|
||||||
havePosition = PR_FALSE;
|
havePosition = PR_FALSE,
|
||||||
|
haveSomething = PR_FALSE;
|
||||||
while (GetToken(PR_TRUE)) {
|
while (GetToken(PR_TRUE)) {
|
||||||
nsCSSTokenType tt = mToken.mType;
|
nsCSSTokenType tt = mToken.mType;
|
||||||
UngetToken(); // ...but we'll still cheat and use mToken
|
UngetToken(); // ...but we'll still cheat and use mToken
|
||||||
|
@ -5908,7 +6008,7 @@ CSSParserImpl::ParseBackground()
|
||||||
PRInt32 dummy;
|
PRInt32 dummy;
|
||||||
if (keyword == eCSSKeyword_inherit ||
|
if (keyword == eCSSKeyword_inherit ||
|
||||||
keyword == eCSSKeyword__moz_initial) {
|
keyword == eCSSKeyword__moz_initial) {
|
||||||
if (haveColor || haveImage || haveRepeat || haveAttach || havePosition)
|
if (haveSomething || !aFirstItem)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
haveColor = haveImage = haveRepeat = haveAttach = havePosition =
|
haveColor = haveImage = haveRepeat = haveAttach = havePosition =
|
||||||
PR_TRUE;
|
PR_TRUE;
|
||||||
|
@ -5919,24 +6019,21 @@ CSSParserImpl::ParseBackground()
|
||||||
} else {
|
} else {
|
||||||
val.SetInitialValue();
|
val.SetInitialValue();
|
||||||
}
|
}
|
||||||
mTempData.mColor.mBackColor = val;
|
mTempData.mColor.mBackColor.SetBothValuesTo(val);
|
||||||
mTempData.mColor.mBackImage = val;
|
aItem.mImage = val;
|
||||||
mTempData.mColor.mBackRepeat = val;
|
aItem.mRepeat = val;
|
||||||
mTempData.mColor.mBackAttachment = val;
|
aItem.mAttachment = val;
|
||||||
mTempData.mColor.mBackPosition.mXValue = val;
|
aItem.mPosition.SetBothValuesTo(val);
|
||||||
mTempData.mColor.mBackPosition.mYValue = val;
|
aItem.mClip = val;
|
||||||
// Reset (for 'inherit') the 3 properties that can't be
|
aItem.mOrigin = val;
|
||||||
// specified, although it's not entirely clear in the spec:
|
aItem.mLastItem = PR_TRUE;
|
||||||
// http://lists.w3.org/Archives/Public/www-style/2007Mar/0110
|
haveSomething = PR_TRUE;
|
||||||
mTempData.mColor.mBackClip = val;
|
|
||||||
mTempData.mColor.mBackOrigin = val;
|
|
||||||
mTempData.mColor.mBackInlinePolicy = val;
|
|
||||||
break;
|
break;
|
||||||
} else if (keyword == eCSSKeyword_none) {
|
} else if (keyword == eCSSKeyword_none) {
|
||||||
if (haveImage)
|
if (haveImage)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
haveImage = PR_TRUE;
|
haveImage = PR_TRUE;
|
||||||
if (!ParseSingleValueProperty(mTempData.mColor.mBackImage,
|
if (!ParseSingleValueProperty(aItem.mImage,
|
||||||
eCSSProperty_background_image)) {
|
eCSSProperty_background_image)) {
|
||||||
NS_NOTREACHED("should be able to parse");
|
NS_NOTREACHED("should be able to parse");
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
|
@ -5946,7 +6043,7 @@ CSSParserImpl::ParseBackground()
|
||||||
if (haveAttach)
|
if (haveAttach)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
haveAttach = PR_TRUE;
|
haveAttach = PR_TRUE;
|
||||||
if (!ParseSingleValueProperty(mTempData.mColor.mBackAttachment,
|
if (!ParseSingleValueProperty(aItem.mAttachment,
|
||||||
eCSSProperty_background_attachment)) {
|
eCSSProperty_background_attachment)) {
|
||||||
NS_NOTREACHED("should be able to parse");
|
NS_NOTREACHED("should be able to parse");
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
|
@ -5956,7 +6053,7 @@ CSSParserImpl::ParseBackground()
|
||||||
if (haveRepeat)
|
if (haveRepeat)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
haveRepeat = PR_TRUE;
|
haveRepeat = PR_TRUE;
|
||||||
if (!ParseSingleValueProperty(mTempData.mColor.mBackRepeat,
|
if (!ParseSingleValueProperty(aItem.mRepeat,
|
||||||
eCSSProperty_background_repeat)) {
|
eCSSProperty_background_repeat)) {
|
||||||
NS_NOTREACHED("should be able to parse");
|
NS_NOTREACHED("should be able to parse");
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
|
@ -5966,24 +6063,57 @@ CSSParserImpl::ParseBackground()
|
||||||
if (havePosition)
|
if (havePosition)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
havePosition = PR_TRUE;
|
havePosition = PR_TRUE;
|
||||||
if (!ParseBackgroundPositionValues()) {
|
if (!ParseBoxPositionValues(aItem.mPosition)) {
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
// This is commented out for now until we change
|
||||||
|
// -moz-background-clip to background-clip, -moz-background-origin
|
||||||
|
// to background-origin, change their value names to *-box, and add
|
||||||
|
// support for content-box on background-clip.
|
||||||
|
} else if (nsCSSProps::FindKeyword(keyword,
|
||||||
|
nsCSSProps::kBackgroundClipKTable, dummy)) {
|
||||||
|
// For now, we use the background-clip table, because we don't
|
||||||
|
// support 'content' on background-clip. But that's dangerous
|
||||||
|
// if we eventually support no-clip.
|
||||||
|
NS_ASSERTION(
|
||||||
|
nsCSSProps::kBackgroundClipKTable[0] == eCSSKeyword_border &&
|
||||||
|
nsCSSProps::kBackgroundClipKTable[2] == eCSSKeyword_padding &&
|
||||||
|
nsCSSProps::kBackgroundClipKTable[4] == eCSSKeyword_UNKNOWN,
|
||||||
|
"need to rewrite this code");
|
||||||
|
if (haveOrigin)
|
||||||
|
return PR_FALSE;
|
||||||
|
haveOrigin = PR_TRUE;
|
||||||
|
if (!ParseSingleValueProperty(aItem.mOrigin,
|
||||||
|
eCSSProperty__moz_background_origin)) {
|
||||||
|
NS_NOTREACHED("should be able to parse");
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_BORDER ==
|
||||||
|
NS_STYLE_BG_ORIGIN_BORDER);
|
||||||
|
PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_PADDING ==
|
||||||
|
NS_STYLE_BG_ORIGIN_PADDING);
|
||||||
|
// PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_CONTENT == /* does not exist */
|
||||||
|
// NS_STYLE_BG_ORIGIN_CONTENT);
|
||||||
|
// When we support 'no-clip', this needs to be conditional on haveClip:
|
||||||
|
aItem.mClip = aItem.mOrigin;
|
||||||
|
// We'd support 'no-clip' as an additional |else| here.
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (haveColor)
|
if (haveColor)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
haveColor = PR_TRUE;
|
haveColor = PR_TRUE;
|
||||||
if (!ParseSingleValueProperty(mTempData.mColor.mBackColor,
|
if (!ParseBackgroundColor(PR_TRUE)) {
|
||||||
eCSSProperty_background_color)) {
|
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
aItem.mLastItem = PR_TRUE;
|
||||||
}
|
}
|
||||||
} else if (eCSSToken_Function == tt &&
|
} else if (eCSSToken_Function == tt &&
|
||||||
mToken.mIdent.LowerCaseEqualsLiteral("url")) {
|
mToken.mIdent.LowerCaseEqualsLiteral("url")) {
|
||||||
if (haveImage)
|
if (haveImage)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
haveImage = PR_TRUE;
|
haveImage = PR_TRUE;
|
||||||
if (!ParseSingleValueProperty(mTempData.mColor.mBackImage,
|
if (!ParseSingleValueProperty(aItem.mImage,
|
||||||
eCSSProperty_background_image)) {
|
eCSSProperty_background_image)) {
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -5991,37 +6121,131 @@ CSSParserImpl::ParseBackground()
|
||||||
if (havePosition)
|
if (havePosition)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
havePosition = PR_TRUE;
|
havePosition = PR_TRUE;
|
||||||
if (!ParseBackgroundPositionValues()) {
|
if (!ParseBoxPositionValues(aItem.mPosition)) {
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (haveColor)
|
if (haveColor)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
haveColor = PR_TRUE;
|
haveColor = PR_TRUE;
|
||||||
if (!ParseSingleValueProperty(mTempData.mColor.mBackColor,
|
// Note: ParseBackgroundColor parses 'inherit' and 'initial', but
|
||||||
eCSSProperty_background_color)) {
|
// we've already checked for them, so it's ok.
|
||||||
|
if (!ParseBackgroundColor(PR_TRUE)) {
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
aItem.mLastItem = PR_TRUE;
|
||||||
}
|
}
|
||||||
|
haveSomething = PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ExpectEndProperty() &&
|
return haveSomething;
|
||||||
(haveColor || haveImage || haveRepeat || haveAttach || havePosition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function is very similar to ParseBackgroundPosition.
|
||||||
|
PRBool
|
||||||
|
CSSParserImpl::ParseBackgroundList(nsCSSProperty aPropID)
|
||||||
|
{
|
||||||
|
// aPropID is a single value prop-id
|
||||||
|
nsCSSValue value;
|
||||||
|
nsCSSValueList *head = nsnull, **tail = &head;
|
||||||
|
for (;;) {
|
||||||
|
if (!ParseSingleValueProperty(value, aPropID)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
PRBool inheritOrInitial = value.GetUnit() == eCSSUnit_Inherit ||
|
||||||
|
value.GetUnit() == eCSSUnit_Initial;
|
||||||
|
if (inheritOrInitial && head) {
|
||||||
|
// inherit and initial are only allowed on their own
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nsCSSValueList *item = new nsCSSValueList;
|
||||||
|
if (!item) {
|
||||||
|
mScanner.SetLowLevelError(NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
item->mValue = value;
|
||||||
|
*tail = item;
|
||||||
|
tail = &item->mNext;
|
||||||
|
if (!inheritOrInitial && ExpectSymbol(',', PR_TRUE)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!ExpectEndProperty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nsCSSValueList **source =
|
||||||
|
static_cast<nsCSSValueList**>(mTempData.PropertyAt(aPropID));
|
||||||
|
*source = head;
|
||||||
|
mTempData.SetPropertyBit(aPropID);
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
delete head;
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
CSSParserImpl::ParseBackgroundColor(PRBool aInShorthand)
|
||||||
|
{
|
||||||
|
nsCSSValuePair &backColor = mTempData.mColor.mBackColor;
|
||||||
|
mTempData.SetPropertyBit(eCSSProperty_background_color);
|
||||||
|
if (!ParseVariant(backColor.mXValue,
|
||||||
|
aInShorthand ? VARIANT_COLOR : VARIANT_HC, nsnull)) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
backColor.mYValue = backColor.mXValue;
|
||||||
|
switch (backColor.mXValue.GetUnit()) {
|
||||||
|
case eCSSUnit_Inherit:
|
||||||
|
case eCSSUnit_Initial:
|
||||||
|
NS_ASSERTION(!aInShorthand,
|
||||||
|
"should not get inherit or initial in shorthand");
|
||||||
|
return ExpectEndProperty(); // we're done
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore success, since the value is optional.
|
||||||
|
ParseVariant(backColor.mYValue, VARIANT_COLOR, nsnull);
|
||||||
|
|
||||||
|
return aInShorthand || ExpectEndProperty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is very similar to ParseBackgroundList.
|
||||||
PRBool
|
PRBool
|
||||||
CSSParserImpl::ParseBackgroundPosition()
|
CSSParserImpl::ParseBackgroundPosition()
|
||||||
{
|
{
|
||||||
if (!ParseBoxPosition(mTempData.mColor.mBackPosition))
|
// aPropID is a single value prop-id
|
||||||
return PR_FALSE;
|
nsCSSValuePair valuePair;
|
||||||
mTempData.SetPropertyBit(eCSSProperty_background_position);
|
nsCSSValuePairList *head = nsnull, **tail = &head;
|
||||||
return PR_TRUE;
|
for (;;) {
|
||||||
}
|
if (!ParseBoxPositionValues(valuePair)) {
|
||||||
|
break;
|
||||||
PRBool
|
}
|
||||||
CSSParserImpl::ParseBackgroundPositionValues()
|
PRBool inheritOrInitial = valuePair.mXValue.GetUnit() == eCSSUnit_Inherit ||
|
||||||
{
|
valuePair.mXValue.GetUnit() == eCSSUnit_Initial;
|
||||||
return ParseBoxPositionValues(mTempData.mColor.mBackPosition);
|
if (inheritOrInitial && head) {
|
||||||
|
// inherit and initial are only allowed on their own
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nsCSSValuePairList *item = new nsCSSValuePairList;
|
||||||
|
if (!item) {
|
||||||
|
mScanner.SetLowLevelError(NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
item->mXValue = valuePair.mXValue;
|
||||||
|
item->mYValue = valuePair.mYValue;
|
||||||
|
*tail = item;
|
||||||
|
tail = &item->mNext;
|
||||||
|
if (!inheritOrInitial && ExpectSymbol(',', PR_TRUE)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!ExpectEndProperty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mTempData.mColor.mBackPosition = head;
|
||||||
|
mTempData.SetPropertyBit(eCSSProperty_background_position);
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
delete head;
|
||||||
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6032,12 +6256,6 @@ CSSParserImpl::ParseBackgroundPositionValues()
|
||||||
* @param aOut The nsCSSValuePair where to place the result.
|
* @param aOut The nsCSSValuePair where to place the result.
|
||||||
* @return Whether or not the operation succeeded.
|
* @return Whether or not the operation succeeded.
|
||||||
*/
|
*/
|
||||||
PRBool CSSParserImpl::ParseBoxPosition(nsCSSValuePair &aOut)
|
|
||||||
{
|
|
||||||
// Need to read the box positions and the end of the property.
|
|
||||||
return ParseBoxPositionValues(aOut) && ExpectEndProperty();
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool CSSParserImpl::ParseBoxPositionValues(nsCSSValuePair &aOut)
|
PRBool CSSParserImpl::ParseBoxPositionValues(nsCSSValuePair &aOut)
|
||||||
{
|
{
|
||||||
// First try a percentage or a length value
|
// First try a percentage or a length value
|
||||||
|
@ -7214,7 +7432,8 @@ PRBool CSSParserImpl::ParseMozTransform()
|
||||||
PRBool CSSParserImpl::ParseMozTransformOrigin()
|
PRBool CSSParserImpl::ParseMozTransformOrigin()
|
||||||
{
|
{
|
||||||
/* Read in a box position, fail if we can't. */
|
/* Read in a box position, fail if we can't. */
|
||||||
if (!ParseBoxPosition(mTempData.mDisplay.mTransformOrigin))
|
if (!ParseBoxPositionValues(mTempData.mDisplay.mTransformOrigin) ||
|
||||||
|
!ExpectEndProperty())
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
|
|
||||||
/* Set the property bit and return. */
|
/* Set the property bit and return. */
|
||||||
|
|
|
@ -297,14 +297,14 @@ CSS_PROP_FONT(-x-system-font, _x_system_font, X, CSS_PROPERTY_APPLIES_TO_FIRST_L
|
||||||
#endif
|
#endif
|
||||||
CSS_PROP_BACKENDONLY(azimuth, azimuth, Azimuth, 0, Aural, mAzimuth, eCSSType_Value, kAzimuthKTable)
|
CSS_PROP_BACKENDONLY(azimuth, azimuth, Azimuth, 0, Aural, mAzimuth, eCSSType_Value, kAzimuthKTable)
|
||||||
CSS_PROP_SHORTHAND(background, background, Background, 0)
|
CSS_PROP_SHORTHAND(background, background, Background, 0)
|
||||||
CSS_PROP_BACKGROUND(background-attachment, background_attachment, BackgroundAttachment, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Color, mBackAttachment, eCSSType_Value, kBackgroundAttachmentKTable)
|
CSS_PROP_BACKGROUND(background-attachment, background_attachment, BackgroundAttachment, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_VALUE_LIST_USES_COMMAS, Color, mBackAttachment, eCSSType_ValueList, kBackgroundAttachmentKTable)
|
||||||
CSS_PROP_BACKGROUND(-moz-background-clip, _moz_background_clip, MozBackgroundClip, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Color, mBackClip, eCSSType_Value, kBackgroundClipKTable)
|
CSS_PROP_BACKGROUND(-moz-background-clip, _moz_background_clip, MozBackgroundClip, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_VALUE_LIST_USES_COMMAS, Color, mBackClip, eCSSType_ValueList, kBackgroundClipKTable)
|
||||||
CSS_PROP_BACKGROUND(background-color, background_color, BackgroundColor, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Color, mBackColor, eCSSType_Value, nsnull)
|
CSS_PROP_BACKGROUND(background-color, background_color, BackgroundColor, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Color, mBackColor, eCSSType_ValuePair, nsnull)
|
||||||
CSS_PROP_BACKGROUND(background-image, background_image, BackgroundImage, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Color, mBackImage, eCSSType_Value, nsnull)
|
CSS_PROP_BACKGROUND(background-image, background_image, BackgroundImage, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_VALUE_LIST_USES_COMMAS, Color, mBackImage, eCSSType_ValueList, nsnull)
|
||||||
CSS_PROP_BACKGROUND(-moz-background-inline-policy, _moz_background_inline_policy, MozBackgroundInlinePolicy, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Color, mBackInlinePolicy, eCSSType_Value, kBackgroundInlinePolicyKTable)
|
CSS_PROP_BACKGROUND(-moz-background-inline-policy, _moz_background_inline_policy, MozBackgroundInlinePolicy, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Color, mBackInlinePolicy, eCSSType_Value, kBackgroundInlinePolicyKTable)
|
||||||
CSS_PROP_BACKGROUND(-moz-background-origin, _moz_background_origin, MozBackgroundOrigin, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Color, mBackOrigin, eCSSType_Value, kBackgroundOriginKTable)
|
CSS_PROP_BACKGROUND(-moz-background-origin, _moz_background_origin, MozBackgroundOrigin, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_VALUE_LIST_USES_COMMAS, Color, mBackOrigin, eCSSType_ValueList, kBackgroundOriginKTable)
|
||||||
CSS_PROP_BACKGROUND(background-position, background_position, BackgroundPosition, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Color, mBackPosition, eCSSType_ValuePair, kBackgroundPositionKTable)
|
CSS_PROP_BACKGROUND(background-position, background_position, BackgroundPosition, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_VALUE_LIST_USES_COMMAS, Color, mBackPosition, eCSSType_ValuePairList, kBackgroundPositionKTable)
|
||||||
CSS_PROP_BACKGROUND(background-repeat, background_repeat, BackgroundRepeat, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Color, mBackRepeat, eCSSType_Value, kBackgroundRepeatKTable)
|
CSS_PROP_BACKGROUND(background-repeat, background_repeat, BackgroundRepeat, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_VALUE_LIST_USES_COMMAS, Color, mBackRepeat, eCSSType_ValueList, kBackgroundRepeatKTable)
|
||||||
CSS_PROP_DISPLAY(-moz-binding, binding, MozBinding, 0, Display, mBinding, eCSSType_Value, nsnull) // XXX bug 3935
|
CSS_PROP_DISPLAY(-moz-binding, binding, MozBinding, 0, Display, mBinding, eCSSType_Value, nsnull) // XXX bug 3935
|
||||||
CSS_PROP_SHORTHAND(border, border, Border, 0)
|
CSS_PROP_SHORTHAND(border, border, Border, 0)
|
||||||
CSS_PROP_SHORTHAND(border-bottom, border_bottom, BorderBottom, 0)
|
CSS_PROP_SHORTHAND(border-bottom, border_bottom, BorderBottom, 0)
|
||||||
|
|
|
@ -1489,9 +1489,8 @@ static const nsCSSProperty gBackgroundSubpropTable[] = {
|
||||||
eCSSProperty_background_repeat,
|
eCSSProperty_background_repeat,
|
||||||
eCSSProperty_background_attachment,
|
eCSSProperty_background_attachment,
|
||||||
eCSSProperty_background_position,
|
eCSSProperty_background_position,
|
||||||
eCSSProperty__moz_background_clip, // XXX Added LDB.
|
eCSSProperty__moz_background_clip,
|
||||||
eCSSProperty__moz_background_origin, // XXX Added LDB.
|
eCSSProperty__moz_background_origin,
|
||||||
eCSSProperty__moz_background_inline_policy, // XXX Added LDB.
|
|
||||||
eCSSProperty_UNKNOWN
|
eCSSProperty_UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,12 @@ nsCSSValueList::Equal(nsCSSValueList* aList1, nsCSSValueList* aList2)
|
||||||
// --- nsCSSColor -----------------
|
// --- nsCSSColor -----------------
|
||||||
|
|
||||||
nsCSSColor::nsCSSColor(void)
|
nsCSSColor::nsCSSColor(void)
|
||||||
|
: mBackImage(nsnull)
|
||||||
|
, mBackRepeat(nsnull)
|
||||||
|
, mBackAttachment(nsnull)
|
||||||
|
, mBackPosition(nsnull)
|
||||||
|
, mBackClip(nsnull)
|
||||||
|
, mBackOrigin(nsnull)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(nsCSSColor);
|
MOZ_COUNT_CTOR(nsCSSColor);
|
||||||
}
|
}
|
||||||
|
@ -113,6 +119,13 @@ nsCSSColor::nsCSSColor(void)
|
||||||
nsCSSColor::~nsCSSColor(void)
|
nsCSSColor::~nsCSSColor(void)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_DTOR(nsCSSColor);
|
MOZ_COUNT_DTOR(nsCSSColor);
|
||||||
|
|
||||||
|
delete mBackImage;
|
||||||
|
delete mBackRepeat;
|
||||||
|
delete mBackAttachment;
|
||||||
|
delete mBackPosition;
|
||||||
|
delete mBackClip;
|
||||||
|
delete mBackOrigin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- nsCSSText -----------------
|
// --- nsCSSText -----------------
|
||||||
|
|
|
@ -307,13 +307,13 @@ struct nsCSSColor : public nsCSSStruct {
|
||||||
~nsCSSColor(void);
|
~nsCSSColor(void);
|
||||||
|
|
||||||
nsCSSValue mColor;
|
nsCSSValue mColor;
|
||||||
nsCSSValue mBackColor;
|
nsCSSValuePair mBackColor;
|
||||||
nsCSSValue mBackImage;
|
nsCSSValueList* mBackImage;
|
||||||
nsCSSValue mBackRepeat;
|
nsCSSValueList* mBackRepeat;
|
||||||
nsCSSValue mBackAttachment;
|
nsCSSValueList* mBackAttachment;
|
||||||
nsCSSValuePair mBackPosition;
|
nsCSSValuePairList* mBackPosition;
|
||||||
nsCSSValue mBackClip;
|
nsCSSValueList* mBackClip;
|
||||||
nsCSSValue mBackOrigin;
|
nsCSSValueList* mBackOrigin;
|
||||||
nsCSSValue mBackInlinePolicy;
|
nsCSSValue mBackInlinePolicy;
|
||||||
private:
|
private:
|
||||||
nsCSSColor(const nsCSSColor& aOther); // NOT IMPLEMENTED
|
nsCSSColor(const nsCSSColor& aOther); // NOT IMPLEMENTED
|
||||||
|
@ -321,6 +321,11 @@ private:
|
||||||
|
|
||||||
struct nsRuleDataColor : public nsCSSColor {
|
struct nsRuleDataColor : public nsCSSColor {
|
||||||
nsRuleDataColor() {}
|
nsRuleDataColor() {}
|
||||||
|
|
||||||
|
// A little bit of a hack here: now that background-image is
|
||||||
|
// represented by a value list, attribute mapping code needs a place
|
||||||
|
// to store one item in a value list in order to map a simple value.
|
||||||
|
nsCSSValueList mTempBackImage;
|
||||||
private:
|
private:
|
||||||
nsRuleDataColor(const nsRuleDataColor& aOther); // NOT IMPLEMENTED
|
nsRuleDataColor(const nsRuleDataColor& aOther); // NOT IMPLEMENTED
|
||||||
};
|
};
|
||||||
|
|
|
@ -1165,69 +1165,117 @@ nsComputedDOMStyle::GetFontVariant(nsIDOMCSSValue** aValue)
|
||||||
return CallQueryInterface(val, aValue);
|
return CallQueryInterface(val, aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsComputedDOMStyle::GetBackgroundList(PRUint8 nsStyleBackground::Layer::* aMember,
|
||||||
|
PRUint32 nsStyleBackground::* aCount,
|
||||||
|
const PRInt32 aTable[],
|
||||||
|
nsIDOMCSSValue** aResult)
|
||||||
|
{
|
||||||
|
const nsStyleBackground* bg = GetStyleBackground();
|
||||||
|
|
||||||
|
nsDOMCSSValueList *valueList = GetROCSSValueList(PR_TRUE);
|
||||||
|
NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
|
for (PRUint32 i = 0, i_end = bg->*aCount; i < i_end; ++i) {
|
||||||
|
nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
|
||||||
|
if (!val || !valueList->AppendCSSValue(val)) {
|
||||||
|
delete val;
|
||||||
|
delete valueList;
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
val->SetIdent(nsCSSProps::ValueToKeywordEnum(bg->mLayers[i].*aMember,
|
||||||
|
aTable));
|
||||||
|
}
|
||||||
|
|
||||||
|
return CallQueryInterface(valueList, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsComputedDOMStyle::GetBackgroundAttachment(nsIDOMCSSValue** aValue)
|
nsComputedDOMStyle::GetBackgroundAttachment(nsIDOMCSSValue** aValue)
|
||||||
{
|
{
|
||||||
nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
|
return GetBackgroundList(&nsStyleBackground::Layer::mAttachment,
|
||||||
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
|
&nsStyleBackground::mAttachmentCount,
|
||||||
|
nsCSSProps::kBackgroundAttachmentKTable,
|
||||||
const nsStyleBackground *background = GetStyleBackground();
|
aValue);
|
||||||
|
|
||||||
val->SetIdent(
|
|
||||||
nsCSSProps::ValueToKeywordEnum(background->mBackgroundAttachment,
|
|
||||||
nsCSSProps::kBackgroundAttachmentKTable));
|
|
||||||
|
|
||||||
return CallQueryInterface(val, aValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsComputedDOMStyle::GetBackgroundClip(nsIDOMCSSValue** aValue)
|
nsComputedDOMStyle::GetBackgroundClip(nsIDOMCSSValue** aValue)
|
||||||
{
|
{
|
||||||
nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
|
return GetBackgroundList(&nsStyleBackground::Layer::mClip,
|
||||||
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
|
&nsStyleBackground::mClipCount,
|
||||||
|
nsCSSProps::kBackgroundClipKTable,
|
||||||
val->SetIdent(
|
aValue);
|
||||||
nsCSSProps::ValueToKeywordEnum(GetStyleBackground()->mBackgroundClip,
|
|
||||||
nsCSSProps::kBackgroundClipKTable));
|
|
||||||
|
|
||||||
return CallQueryInterface(val, aValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsComputedDOMStyle::GetBackgroundColor(nsIDOMCSSValue** aValue)
|
nsComputedDOMStyle::GetBackgroundColor(nsIDOMCSSValue** aValue)
|
||||||
{
|
{
|
||||||
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
|
const nsStyleBackground* bg = GetStyleBackground();
|
||||||
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
|
nsresult rv;
|
||||||
|
|
||||||
const nsStyleBackground* color = GetStyleBackground();
|
if (bg->mBackgroundColor == bg->mFallbackBackgroundColor) {
|
||||||
nsresult rv = SetToRGBAColor(val, color->mBackgroundColor);
|
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
|
||||||
if (NS_FAILED(rv)) {
|
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
|
||||||
delete val;
|
|
||||||
return rv;
|
rv = SetToRGBAColor(val, bg->mBackgroundColor);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
delete val;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
rv = CallQueryInterface(val, aValue);
|
||||||
|
} else {
|
||||||
|
nsDOMCSSValueList *valueList = GetROCSSValueList(PR_FALSE);
|
||||||
|
NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
|
for (PRUint32 i = 0; i < 2; ++i) {
|
||||||
|
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
|
||||||
|
if (!val || !valueList->AppendCSSValue(val)) {
|
||||||
|
delete val;
|
||||||
|
delete valueList;
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = SetToRGBAColor(val, (i == 0) ? bg->mBackgroundColor
|
||||||
|
: bg->mFallbackBackgroundColor);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
delete valueList;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rv = CallQueryInterface(valueList, aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CallQueryInterface(val, aValue);
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsComputedDOMStyle::GetBackgroundImage(nsIDOMCSSValue** aValue)
|
nsComputedDOMStyle::GetBackgroundImage(nsIDOMCSSValue** aValue)
|
||||||
{
|
{
|
||||||
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
|
const nsStyleBackground* bg = GetStyleBackground();
|
||||||
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
|
|
||||||
const nsStyleBackground* color = GetStyleBackground();
|
nsDOMCSSValueList *valueList = GetROCSSValueList(PR_TRUE);
|
||||||
|
NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
if (color->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE) {
|
for (PRUint32 i = 0, i_end = bg->mImageCount; i < i_end; ++i) {
|
||||||
val->SetIdent(eCSSKeyword_none);
|
nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
|
||||||
} else {
|
if (!val || !valueList->AppendCSSValue(val)) {
|
||||||
nsCOMPtr<nsIURI> uri;
|
delete val;
|
||||||
if (color->mBackgroundImage) {
|
delete valueList;
|
||||||
color->mBackgroundImage->GetURI(getter_AddRefs(uri));
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
imgIRequest *image = bg->mLayers[i].mImage.mRequest;
|
||||||
|
if (!image) {
|
||||||
|
val->SetIdent(eCSSKeyword_none);
|
||||||
|
} else {
|
||||||
|
nsCOMPtr<nsIURI> uri;
|
||||||
|
image->GetURI(getter_AddRefs(uri));
|
||||||
|
val->SetURI(uri);
|
||||||
}
|
}
|
||||||
val->SetURI(uri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return CallQueryInterface(val, aValue);
|
return CallQueryInterface(valueList, aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -1246,56 +1294,55 @@ nsComputedDOMStyle::GetBackgroundInlinePolicy(nsIDOMCSSValue** aValue)
|
||||||
nsresult
|
nsresult
|
||||||
nsComputedDOMStyle::GetBackgroundOrigin(nsIDOMCSSValue** aValue)
|
nsComputedDOMStyle::GetBackgroundOrigin(nsIDOMCSSValue** aValue)
|
||||||
{
|
{
|
||||||
nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
|
return GetBackgroundList(&nsStyleBackground::Layer::mOrigin,
|
||||||
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
|
&nsStyleBackground::mOriginCount,
|
||||||
|
nsCSSProps::kBackgroundOriginKTable,
|
||||||
val->SetIdent(
|
aValue);
|
||||||
nsCSSProps::ValueToKeywordEnum(GetStyleBackground()->mBackgroundOrigin,
|
|
||||||
nsCSSProps::kBackgroundOriginKTable));
|
|
||||||
|
|
||||||
return CallQueryInterface(val, aValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsComputedDOMStyle::GetBackgroundPosition(nsIDOMCSSValue** aValue)
|
nsComputedDOMStyle::GetBackgroundPosition(nsIDOMCSSValue** aValue)
|
||||||
{
|
{
|
||||||
nsDOMCSSValueList *valueList = GetROCSSValueList(PR_FALSE);
|
const nsStyleBackground* bg = GetStyleBackground();
|
||||||
|
|
||||||
|
nsDOMCSSValueList *valueList = GetROCSSValueList(PR_TRUE);
|
||||||
NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
nsROCSSPrimitiveValue *valX = GetROCSSPrimitiveValue();
|
for (PRUint32 i = 0, i_end = bg->mPositionCount; i < i_end; ++i) {
|
||||||
if (!valX || !valueList->AppendCSSValue(valX)) {
|
nsDOMCSSValueList *itemList = GetROCSSValueList(PR_FALSE);
|
||||||
delete valueList;
|
if (!itemList || !valueList->AppendCSSValue(itemList)) {
|
||||||
delete valX;
|
delete valueList;
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
delete itemList;
|
||||||
}
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
nsROCSSPrimitiveValue *valY = GetROCSSPrimitiveValue();
|
nsROCSSPrimitiveValue *valX = GetROCSSPrimitiveValue();
|
||||||
if (!valY || !valueList->AppendCSSValue(valY)) {
|
if (!valX || !itemList->AppendCSSValue(valX)) {
|
||||||
delete valueList;
|
delete valueList;
|
||||||
delete valY;
|
delete valX;
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nsStyleBackground *bg = GetStyleBackground();
|
nsROCSSPrimitiveValue *valY = GetROCSSPrimitiveValue();
|
||||||
|
if (!valY || !itemList->AppendCSSValue(valY)) {
|
||||||
|
delete valueList;
|
||||||
|
delete valY;
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
if (NS_STYLE_BG_X_POSITION_LENGTH & bg->mBackgroundFlags) {
|
const nsStyleBackground::Position &pos = bg->mLayers[i].mPosition;
|
||||||
valX->SetAppUnits(bg->mBackgroundXPosition.mCoord);
|
|
||||||
}
|
|
||||||
else if (NS_STYLE_BG_X_POSITION_PERCENT & bg->mBackgroundFlags) {
|
|
||||||
valX->SetPercent(bg->mBackgroundXPosition.mFloat);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
valX->SetPercent(0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_STYLE_BG_Y_POSITION_LENGTH & bg->mBackgroundFlags) {
|
if (pos.mXIsPercent) {
|
||||||
valY->SetAppUnits(bg->mBackgroundYPosition.mCoord);
|
valX->SetPercent(pos.mXPosition.mFloat);
|
||||||
}
|
} else {
|
||||||
else if (NS_STYLE_BG_Y_POSITION_PERCENT & bg->mBackgroundFlags) {
|
valX->SetAppUnits(pos.mXPosition.mCoord);
|
||||||
valY->SetPercent(bg->mBackgroundYPosition.mFloat);
|
}
|
||||||
}
|
|
||||||
else {
|
if (pos.mYIsPercent) {
|
||||||
valY->SetPercent(0.0f);
|
valY->SetPercent(pos.mYPosition.mFloat);
|
||||||
|
} else {
|
||||||
|
valY->SetAppUnits(pos.mYPosition.mCoord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CallQueryInterface(valueList, aValue);
|
return CallQueryInterface(valueList, aValue);
|
||||||
|
@ -1304,14 +1351,10 @@ nsComputedDOMStyle::GetBackgroundPosition(nsIDOMCSSValue** aValue)
|
||||||
nsresult
|
nsresult
|
||||||
nsComputedDOMStyle::GetBackgroundRepeat(nsIDOMCSSValue** aValue)
|
nsComputedDOMStyle::GetBackgroundRepeat(nsIDOMCSSValue** aValue)
|
||||||
{
|
{
|
||||||
nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
|
return GetBackgroundList(&nsStyleBackground::Layer::mRepeat,
|
||||||
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
|
&nsStyleBackground::mRepeatCount,
|
||||||
|
nsCSSProps::kBackgroundRepeatKTable,
|
||||||
val->SetIdent(
|
aValue);
|
||||||
nsCSSProps::ValueToKeywordEnum(GetStyleBackground()->mBackgroundRepeat,
|
|
||||||
nsCSSProps::kBackgroundRepeatKTable));
|
|
||||||
|
|
||||||
return CallQueryInterface(val, aValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -1831,7 +1874,7 @@ nsComputedDOMStyle::GetCSSShadowArray(nsCSSShadowArray* aArray,
|
||||||
NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
for (nsCSSShadowItem *item = aArray->ShadowAt(0),
|
for (nsCSSShadowItem *item = aArray->ShadowAt(0),
|
||||||
*item_end = item + aArray->Length();
|
*item_end = item + aArray->Length();
|
||||||
item < item_end; ++item) {
|
item < item_end; ++item) {
|
||||||
nsDOMCSSValueList *itemList = GetROCSSValueList(PR_FALSE);
|
nsDOMCSSValueList *itemList = GetROCSSValueList(PR_FALSE);
|
||||||
if (!itemList || !valueList->AppendCSSValue(itemList)) {
|
if (!itemList || !valueList->AppendCSSValue(itemList)) {
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsWeakReference.h"
|
#include "nsWeakReference.h"
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsStyleStruct.h"
|
||||||
|
|
||||||
class nsComputedDOMStyle : public nsIComputedDOMStyle
|
class nsComputedDOMStyle : public nsIComputedDOMStyle
|
||||||
{
|
{
|
||||||
|
@ -116,6 +117,11 @@ private:
|
||||||
PRBool aIsBoxShadow,
|
PRBool aIsBoxShadow,
|
||||||
nsIDOMCSSValue** aValue);
|
nsIDOMCSSValue** aValue);
|
||||||
|
|
||||||
|
nsresult GetBackgroundList(PRUint8 nsStyleBackground::Layer::* aMember,
|
||||||
|
PRUint32 nsStyleBackground::* aCount,
|
||||||
|
const PRInt32 aTable[],
|
||||||
|
nsIDOMCSSValue** aResult);
|
||||||
|
|
||||||
/* Properties Queryable as CSSValues */
|
/* Properties Queryable as CSSValues */
|
||||||
|
|
||||||
nsresult GetAppearance(nsIDOMCSSValue** aValue);
|
nsresult GetAppearance(nsIDOMCSSValue** aValue);
|
||||||
|
|
|
@ -1420,8 +1420,7 @@ nsRuleNode::GetUIResetData(nsStyleContext* aContext)
|
||||||
nsRuleData ruleData(NS_STYLE_INHERIT_BIT(UIReset), mPresContext, aContext);
|
nsRuleData ruleData(NS_STYLE_INHERIT_BIT(UIReset), mPresContext, aContext);
|
||||||
ruleData.mUserInterfaceData = &uiData;
|
ruleData.mUserInterfaceData = &uiData;
|
||||||
|
|
||||||
const void* res = WalkRuleTree(eStyleStruct_UIReset, aContext, &ruleData, &uiData);
|
return WalkRuleTree(eStyleStruct_UIReset, aContext, &ruleData, &uiData);
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const void*
|
const void*
|
||||||
|
@ -1455,7 +1454,17 @@ nsRuleNode::GetBackgroundData(nsStyleContext* aContext)
|
||||||
// null in HasAuthorSpecifiedRules (look at mBoxShadow in GetBorderData
|
// null in HasAuthorSpecifiedRules (look at mBoxShadow in GetBorderData
|
||||||
// and HasAuthorSpecifiedRules).
|
// and HasAuthorSpecifiedRules).
|
||||||
|
|
||||||
return WalkRuleTree(eStyleStruct_Background, aContext, &ruleData, &colorData);
|
const void *res = WalkRuleTree(eStyleStruct_Background, aContext, &ruleData, &colorData);
|
||||||
|
|
||||||
|
// We are sharing with some style rule. It really owns the data.
|
||||||
|
colorData.mBackImage = nsnull;
|
||||||
|
colorData.mBackRepeat = nsnull;
|
||||||
|
colorData.mBackAttachment = nsnull;
|
||||||
|
colorData.mBackPosition = nsnull;
|
||||||
|
colorData.mBackClip = nsnull;
|
||||||
|
colorData.mBackOrigin = nsnull;
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void*
|
const void*
|
||||||
|
@ -3771,6 +3780,189 @@ nsRuleNode::ComputeColorData(void* aStartStruct,
|
||||||
COMPUTE_END_INHERITED(Color, color)
|
COMPUTE_END_INHERITED(Color, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// information about how to compute values for background-* properties
|
||||||
|
template <class SpecifiedValueItem>
|
||||||
|
struct InitialInheritLocationFor {
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_SPECIALIZE_TEMPLATE
|
||||||
|
struct InitialInheritLocationFor<nsCSSValueList> {
|
||||||
|
static nsCSSValue nsCSSValueList::* Location() {
|
||||||
|
return &nsCSSValueList::mValue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_SPECIALIZE_TEMPLATE
|
||||||
|
struct InitialInheritLocationFor<nsCSSValuePairList> {
|
||||||
|
static nsCSSValue nsCSSValuePairList::* Location() {
|
||||||
|
return &nsCSSValuePairList::mXValue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class SpecifiedValueItem, class ComputedValueItem>
|
||||||
|
struct BackgroundItemComputer {
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_SPECIALIZE_TEMPLATE
|
||||||
|
struct BackgroundItemComputer<nsCSSValueList, PRUint8>
|
||||||
|
{
|
||||||
|
static void ComputeValue(nsStyleContext* aStyleContext,
|
||||||
|
const nsCSSValueList* aSpecifiedValue,
|
||||||
|
PRUint8& aComputedValue,
|
||||||
|
PRBool& aCanStoreInRuleTree)
|
||||||
|
{
|
||||||
|
SetDiscrete(aSpecifiedValue->mValue, aComputedValue, aCanStoreInRuleTree,
|
||||||
|
SETDSC_ENUMERATED, PRUint8(0), 0, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_SPECIALIZE_TEMPLATE
|
||||||
|
struct BackgroundItemComputer<nsCSSValueList, nsStyleBackground::Image>
|
||||||
|
{
|
||||||
|
static void ComputeValue(nsStyleContext* aStyleContext,
|
||||||
|
const nsCSSValueList* aSpecifiedValue,
|
||||||
|
nsStyleBackground::Image& aComputedValue,
|
||||||
|
PRBool& aCanStoreInRuleTree)
|
||||||
|
{
|
||||||
|
const nsCSSValue &value = aSpecifiedValue->mValue;
|
||||||
|
if (eCSSUnit_Image == value.GetUnit()) {
|
||||||
|
aComputedValue.mRequest = value.GetImageValue();
|
||||||
|
aComputedValue.mSpecified = PR_TRUE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NS_ASSERTION(eCSSUnit_None == value.GetUnit(), "unexpected unit");
|
||||||
|
aComputedValue.mRequest = nsnull;
|
||||||
|
aComputedValue.mSpecified = PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BackgroundPositionAxis {
|
||||||
|
nsCSSValue nsCSSValuePairList::*specified;
|
||||||
|
nsStyleBackground::Position::PositionCoord
|
||||||
|
nsStyleBackground::Position::*result;
|
||||||
|
PRPackedBool nsStyleBackground::Position::*isPercent;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const BackgroundPositionAxis gBGPosAxes[] = {
|
||||||
|
{ &nsCSSValuePairList::mXValue,
|
||||||
|
&nsStyleBackground::Position::mXPosition,
|
||||||
|
&nsStyleBackground::Position::mXIsPercent },
|
||||||
|
{ &nsCSSValuePairList::mYValue,
|
||||||
|
&nsStyleBackground::Position::mYPosition,
|
||||||
|
&nsStyleBackground::Position::mYIsPercent }
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_SPECIALIZE_TEMPLATE
|
||||||
|
struct BackgroundItemComputer<nsCSSValuePairList, nsStyleBackground::Position>
|
||||||
|
{
|
||||||
|
static void ComputeValue(nsStyleContext* aStyleContext,
|
||||||
|
const nsCSSValuePairList* aSpecifiedValue,
|
||||||
|
nsStyleBackground::Position& aComputedValue,
|
||||||
|
PRBool& aCanStoreInRuleTree)
|
||||||
|
{
|
||||||
|
nsStyleBackground::Position &position = aComputedValue;
|
||||||
|
for (const BackgroundPositionAxis *axis = gBGPosAxes,
|
||||||
|
*axis_end = gBGPosAxes + NS_ARRAY_LENGTH(gBGPosAxes);
|
||||||
|
axis != axis_end; ++axis) {
|
||||||
|
const nsCSSValue &specified = aSpecifiedValue->*(axis->specified);
|
||||||
|
if (eCSSUnit_Percent == specified.GetUnit()) {
|
||||||
|
(position.*(axis->result)).mFloat = specified.GetPercentValue();
|
||||||
|
position.*(axis->isPercent) = PR_TRUE;
|
||||||
|
}
|
||||||
|
else if (specified.IsLengthUnit()) {
|
||||||
|
(position.*(axis->result)).mCoord =
|
||||||
|
CalcLength(specified, aStyleContext, aStyleContext->PresContext(),
|
||||||
|
aCanStoreInRuleTree);
|
||||||
|
position.*(axis->isPercent) = PR_FALSE;
|
||||||
|
}
|
||||||
|
else if (eCSSUnit_Enumerated == specified.GetUnit()) {
|
||||||
|
(position.*(axis->result)).mFloat =
|
||||||
|
GetFloatFromBoxPosition(specified.GetIntValue());
|
||||||
|
position.*(axis->isPercent) = PR_TRUE;
|
||||||
|
} else {
|
||||||
|
NS_NOTREACHED("unexpected unit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class SpecifiedValueItem, class ComputedValueItem>
|
||||||
|
static void
|
||||||
|
SetBackgroundList(nsStyleContext* aStyleContext,
|
||||||
|
const SpecifiedValueItem* aValueList,
|
||||||
|
nsAutoTArray< nsStyleBackground::Layer, 1> &aLayers,
|
||||||
|
const nsAutoTArray<nsStyleBackground::Layer, 1>
|
||||||
|
&aParentLayers,
|
||||||
|
ComputedValueItem nsStyleBackground::Layer::* aResultLocation,
|
||||||
|
ComputedValueItem aInitialValue,
|
||||||
|
PRUint32 aParentItemCount,
|
||||||
|
PRUint32& aItemCount,
|
||||||
|
PRUint32& aMaxItemCount,
|
||||||
|
PRBool& aRebuild,
|
||||||
|
PRBool& aCanStoreInRuleTree)
|
||||||
|
{
|
||||||
|
if (aValueList) {
|
||||||
|
aRebuild = PR_TRUE;
|
||||||
|
nsCSSValue SpecifiedValueItem::* initialInherit =
|
||||||
|
InitialInheritLocationFor<SpecifiedValueItem>::Location();
|
||||||
|
if (eCSSUnit_Inherit == (aValueList->*initialInherit).GetUnit()) {
|
||||||
|
NS_ASSERTION(!aValueList->mNext, "should have only one value");
|
||||||
|
aCanStoreInRuleTree = PR_FALSE;
|
||||||
|
if (!aLayers.EnsureLengthAtLeast(aParentItemCount)) {
|
||||||
|
NS_WARNING("out of memory");
|
||||||
|
aParentItemCount = aLayers.Length();
|
||||||
|
}
|
||||||
|
aItemCount = aParentItemCount;
|
||||||
|
for (PRUint32 i = 0; i < aParentItemCount; ++i) {
|
||||||
|
aLayers[i].*aResultLocation = aParentLayers[i].*aResultLocation;
|
||||||
|
}
|
||||||
|
} else if (eCSSUnit_Initial == (aValueList->*initialInherit).GetUnit()) {
|
||||||
|
NS_ASSERTION(!aValueList->mNext, "should have only one value");
|
||||||
|
aItemCount = 1;
|
||||||
|
aLayers[0].*aResultLocation = aInitialValue;
|
||||||
|
} else {
|
||||||
|
const SpecifiedValueItem *item = aValueList;
|
||||||
|
aItemCount = 0;
|
||||||
|
do {
|
||||||
|
NS_ASSERTION((item->*initialInherit).GetUnit() != eCSSUnit_Inherit &&
|
||||||
|
(item->*initialInherit).GetUnit() != eCSSUnit_Initial,
|
||||||
|
"unexpected unit");
|
||||||
|
++aItemCount;
|
||||||
|
if (!aLayers.EnsureLengthAtLeast(aItemCount)) {
|
||||||
|
NS_WARNING("out of memory");
|
||||||
|
--aItemCount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
BackgroundItemComputer<SpecifiedValueItem, ComputedValueItem>
|
||||||
|
::ComputeValue(aStyleContext, item,
|
||||||
|
aLayers[aItemCount-1].*aResultLocation,
|
||||||
|
aCanStoreInRuleTree);
|
||||||
|
item = item->mNext;
|
||||||
|
} while (item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aItemCount > aMaxItemCount)
|
||||||
|
aMaxItemCount = aItemCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ComputedValueItem>
|
||||||
|
static void
|
||||||
|
FillBackgroundList(nsAutoTArray< nsStyleBackground::Layer, 1> &aLayers,
|
||||||
|
ComputedValueItem nsStyleBackground::Layer::* aResultLocation,
|
||||||
|
PRUint32 aItemCount, PRUint32 aFillCount)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aFillCount <= aLayers.Length(), "unexpected array length");
|
||||||
|
for (PRUint32 sourceLayer = 0, destLayer = aItemCount;
|
||||||
|
destLayer < aFillCount;
|
||||||
|
++sourceLayer, ++destLayer) {
|
||||||
|
aLayers[destLayer].*aResultLocation =
|
||||||
|
aLayers[sourceLayer].*aResultLocation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const void*
|
const void*
|
||||||
nsRuleNode::ComputeBackgroundData(void* aStartStruct,
|
nsRuleNode::ComputeBackgroundData(void* aStartStruct,
|
||||||
const nsRuleDataStruct& aData,
|
const nsRuleDataStruct& aData,
|
||||||
|
@ -3781,52 +3973,55 @@ nsRuleNode::ComputeBackgroundData(void* aStartStruct,
|
||||||
{
|
{
|
||||||
COMPUTE_START_RESET(Background, (), bg, parentBG, Color, colorData)
|
COMPUTE_START_RESET(Background, (), bg, parentBG, Color, colorData)
|
||||||
|
|
||||||
// save parentFlags in case bg == parentBG and we clobber them later
|
// background-color: color, string, inherit [pair]
|
||||||
PRUint8 parentFlags = parentBG->mBackgroundFlags;
|
if (eCSSUnit_Initial == colorData.mBackColor.mXValue.GetUnit()) {
|
||||||
|
|
||||||
// background-color: color, string, inherit
|
|
||||||
if (eCSSUnit_Initial == colorData.mBackColor.GetUnit()) {
|
|
||||||
bg->mBackgroundColor = NS_RGBA(0, 0, 0, 0);
|
bg->mBackgroundColor = NS_RGBA(0, 0, 0, 0);
|
||||||
} else if (!SetColor(colorData.mBackColor, parentBG->mBackgroundColor,
|
} else if (!SetColor(colorData.mBackColor.mXValue,
|
||||||
mPresContext, aContext, bg->mBackgroundColor,
|
parentBG->mBackgroundColor, mPresContext,
|
||||||
canStoreInRuleTree)) {
|
aContext, bg->mBackgroundColor, canStoreInRuleTree)) {
|
||||||
NS_ASSERTION(eCSSUnit_Null == colorData.mBackColor.GetUnit(),
|
NS_ASSERTION(eCSSUnit_Null == colorData.mBackColor.mXValue.GetUnit(),
|
||||||
"unexpected color unit");
|
"unexpected color unit");
|
||||||
}
|
}
|
||||||
|
|
||||||
// background-image: url (stored as image), none, inherit
|
if (eCSSUnit_Initial == colorData.mBackColor.mYValue.GetUnit()) {
|
||||||
if (eCSSUnit_Image == colorData.mBackImage.GetUnit()) {
|
bg->mFallbackBackgroundColor = NS_RGBA(0, 0, 0, 0);
|
||||||
bg->mBackgroundImage = colorData.mBackImage.GetImageValue();
|
} else if (!SetColor(colorData.mBackColor.mYValue,
|
||||||
}
|
parentBG->mFallbackBackgroundColor, mPresContext,
|
||||||
else if (eCSSUnit_None == colorData.mBackImage.GetUnit() ||
|
aContext, bg->mFallbackBackgroundColor,
|
||||||
eCSSUnit_Initial == colorData.mBackImage.GetUnit()) {
|
canStoreInRuleTree)) {
|
||||||
bg->mBackgroundImage = nsnull;
|
NS_ASSERTION(eCSSUnit_Null == colorData.mBackColor.mYValue.GetUnit(),
|
||||||
}
|
"unexpected color unit");
|
||||||
else if (eCSSUnit_Inherit == colorData.mBackImage.GetUnit()) {
|
|
||||||
canStoreInRuleTree = PR_FALSE;
|
|
||||||
bg->mBackgroundImage = parentBG->mBackgroundImage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bg->mBackgroundImage) {
|
PRUint32 maxItemCount = 1;
|
||||||
bg->mBackgroundFlags &= ~NS_STYLE_BG_IMAGE_NONE;
|
PRBool rebuild = PR_FALSE;
|
||||||
} else {
|
|
||||||
bg->mBackgroundFlags |= NS_STYLE_BG_IMAGE_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// background-repeat: enum, inherit, initial
|
// background-image: url (stored as image), none, inherit [list]
|
||||||
SetDiscrete(colorData.mBackRepeat, bg->mBackgroundRepeat, canStoreInRuleTree,
|
SetBackgroundList(aContext, colorData.mBackImage, bg->mLayers,
|
||||||
SETDSC_ENUMERATED, parentBG->mBackgroundRepeat,
|
parentBG->mLayers, &nsStyleBackground::Layer::mImage,
|
||||||
NS_STYLE_BG_REPEAT_XY, 0, 0, 0, 0);
|
nsStyleBackground::Image(), parentBG->mImageCount,
|
||||||
|
bg->mImageCount, maxItemCount, rebuild, canStoreInRuleTree);
|
||||||
|
|
||||||
// background-attachment: enum, inherit, initial
|
// background-repeat: enum, inherit, initial [list]
|
||||||
SetDiscrete(colorData.mBackAttachment, bg->mBackgroundAttachment, canStoreInRuleTree,
|
SetBackgroundList(aContext, colorData.mBackRepeat, bg->mLayers,
|
||||||
SETDSC_ENUMERATED, parentBG->mBackgroundAttachment,
|
parentBG->mLayers, &nsStyleBackground::Layer::mRepeat,
|
||||||
NS_STYLE_BG_ATTACHMENT_SCROLL, 0, 0, 0, 0);
|
PRUint8(NS_STYLE_BG_REPEAT_XY), parentBG->mRepeatCount,
|
||||||
|
bg->mRepeatCount, maxItemCount, rebuild, canStoreInRuleTree);
|
||||||
|
|
||||||
// background-clip: enum, inherit, initial
|
// background-attachment: enum, inherit, initial [list]
|
||||||
SetDiscrete(colorData.mBackClip, bg->mBackgroundClip, canStoreInRuleTree,
|
SetBackgroundList(aContext, colorData.mBackAttachment, bg->mLayers,
|
||||||
SETDSC_ENUMERATED, parentBG->mBackgroundClip,
|
parentBG->mLayers,
|
||||||
NS_STYLE_BG_CLIP_BORDER, 0, 0, 0, 0);
|
&nsStyleBackground::Layer::mAttachment,
|
||||||
|
PRUint8(NS_STYLE_BG_ATTACHMENT_SCROLL),
|
||||||
|
parentBG->mAttachmentCount,
|
||||||
|
bg->mAttachmentCount, maxItemCount, rebuild,
|
||||||
|
canStoreInRuleTree);
|
||||||
|
|
||||||
|
// background-clip: enum, inherit, initial [list]
|
||||||
|
SetBackgroundList(aContext, colorData.mBackClip, bg->mLayers,
|
||||||
|
parentBG->mLayers, &nsStyleBackground::Layer::mClip,
|
||||||
|
PRUint8(NS_STYLE_BG_CLIP_BORDER), parentBG->mClipCount,
|
||||||
|
bg->mClipCount, maxItemCount, rebuild, canStoreInRuleTree);
|
||||||
|
|
||||||
// background-inline-policy: enum, inherit, initial
|
// background-inline-policy: enum, inherit, initial
|
||||||
SetDiscrete(colorData.mBackInlinePolicy, bg->mBackgroundInlinePolicy,
|
SetDiscrete(colorData.mBackInlinePolicy, bg->mBackgroundInlinePolicy,
|
||||||
|
@ -3834,66 +4029,40 @@ nsRuleNode::ComputeBackgroundData(void* aStartStruct,
|
||||||
parentBG->mBackgroundInlinePolicy,
|
parentBG->mBackgroundInlinePolicy,
|
||||||
NS_STYLE_BG_INLINE_POLICY_CONTINUOUS, 0, 0, 0, 0);
|
NS_STYLE_BG_INLINE_POLICY_CONTINUOUS, 0, 0, 0, 0);
|
||||||
|
|
||||||
// background-origin: enum, inherit, initial
|
// background-origin: enum, inherit, initial [list]
|
||||||
SetDiscrete(colorData.mBackOrigin, bg->mBackgroundOrigin, canStoreInRuleTree,
|
SetBackgroundList(aContext, colorData.mBackOrigin, bg->mLayers,
|
||||||
SETDSC_ENUMERATED, parentBG->mBackgroundOrigin,
|
parentBG->mLayers, &nsStyleBackground::Layer::mOrigin,
|
||||||
NS_STYLE_BG_ORIGIN_PADDING, 0, 0, 0, 0);
|
PRUint8(NS_STYLE_BG_ORIGIN_PADDING), parentBG->mOriginCount,
|
||||||
|
bg->mOriginCount, maxItemCount, rebuild,
|
||||||
|
canStoreInRuleTree);
|
||||||
|
|
||||||
// background-position: enum, length, percent (flags), inherit
|
// background-position: enum, length, percent (flags), inherit [pair list]
|
||||||
if (eCSSUnit_Percent == colorData.mBackPosition.mXValue.GetUnit()) {
|
nsStyleBackground::Position initialPosition;
|
||||||
bg->mBackgroundXPosition.mFloat = colorData.mBackPosition.mXValue.GetPercentValue();
|
initialPosition.SetInitialValues();
|
||||||
bg->mBackgroundFlags |= NS_STYLE_BG_X_POSITION_PERCENT;
|
SetBackgroundList(aContext, colorData.mBackPosition, bg->mLayers,
|
||||||
bg->mBackgroundFlags &= ~NS_STYLE_BG_X_POSITION_LENGTH;
|
parentBG->mLayers, &nsStyleBackground::Layer::mPosition,
|
||||||
}
|
initialPosition, parentBG->mPositionCount,
|
||||||
else if (colorData.mBackPosition.mXValue.IsLengthUnit()) {
|
bg->mPositionCount, maxItemCount, rebuild,
|
||||||
bg->mBackgroundXPosition.mCoord = CalcLength(colorData.mBackPosition.mXValue,
|
canStoreInRuleTree);
|
||||||
aContext, mPresContext, canStoreInRuleTree);
|
|
||||||
bg->mBackgroundFlags |= NS_STYLE_BG_X_POSITION_LENGTH;
|
|
||||||
bg->mBackgroundFlags &= ~NS_STYLE_BG_X_POSITION_PERCENT;
|
|
||||||
}
|
|
||||||
else if (eCSSUnit_Enumerated == colorData.mBackPosition.mXValue.GetUnit()) {
|
|
||||||
bg->mBackgroundXPosition.mFloat =
|
|
||||||
GetFloatFromBoxPosition(colorData.mBackPosition.mXValue.GetIntValue());
|
|
||||||
|
|
||||||
bg->mBackgroundFlags |= NS_STYLE_BG_X_POSITION_PERCENT;
|
if (rebuild) {
|
||||||
bg->mBackgroundFlags &= ~NS_STYLE_BG_X_POSITION_LENGTH;
|
// Delete any extra items. We need to keep layers in which any
|
||||||
}
|
// property was specified.
|
||||||
else if (eCSSUnit_Inherit == colorData.mBackPosition.mXValue.GetUnit()) {
|
bg->mLayers.TruncateLength(maxItemCount);
|
||||||
canStoreInRuleTree = PR_FALSE;
|
|
||||||
bg->mBackgroundXPosition = parentBG->mBackgroundXPosition;
|
|
||||||
bg->mBackgroundFlags &= ~(NS_STYLE_BG_X_POSITION_LENGTH | NS_STYLE_BG_X_POSITION_PERCENT);
|
|
||||||
bg->mBackgroundFlags |= (parentFlags & (NS_STYLE_BG_X_POSITION_LENGTH | NS_STYLE_BG_X_POSITION_PERCENT));
|
|
||||||
}
|
|
||||||
else if (eCSSUnit_Initial == colorData.mBackPosition.mXValue.GetUnit()) {
|
|
||||||
bg->mBackgroundFlags &= ~(NS_STYLE_BG_X_POSITION_LENGTH | NS_STYLE_BG_X_POSITION_PERCENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eCSSUnit_Percent == colorData.mBackPosition.mYValue.GetUnit()) {
|
PRUint32 fillCount = bg->mImageCount;
|
||||||
bg->mBackgroundYPosition.mFloat = colorData.mBackPosition.mYValue.GetPercentValue();
|
FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mImage,
|
||||||
bg->mBackgroundFlags |= NS_STYLE_BG_Y_POSITION_PERCENT;
|
bg->mImageCount, fillCount);
|
||||||
bg->mBackgroundFlags &= ~NS_STYLE_BG_Y_POSITION_LENGTH;
|
FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mRepeat,
|
||||||
}
|
bg->mRepeatCount, fillCount);
|
||||||
else if (colorData.mBackPosition.mYValue.IsLengthUnit()) {
|
FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mAttachment,
|
||||||
bg->mBackgroundYPosition.mCoord = CalcLength(colorData.mBackPosition.mYValue,
|
bg->mAttachmentCount, fillCount);
|
||||||
aContext, mPresContext, canStoreInRuleTree);
|
FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mClip,
|
||||||
bg->mBackgroundFlags |= NS_STYLE_BG_Y_POSITION_LENGTH;
|
bg->mClipCount, fillCount);
|
||||||
bg->mBackgroundFlags &= ~NS_STYLE_BG_Y_POSITION_PERCENT;
|
FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mOrigin,
|
||||||
}
|
bg->mOriginCount, fillCount);
|
||||||
else if (eCSSUnit_Enumerated == colorData.mBackPosition.mYValue.GetUnit()) {
|
FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mPosition,
|
||||||
bg->mBackgroundYPosition.mFloat =
|
bg->mPositionCount, fillCount);
|
||||||
GetFloatFromBoxPosition(colorData.mBackPosition.mYValue.GetIntValue());
|
|
||||||
|
|
||||||
bg->mBackgroundFlags |= NS_STYLE_BG_Y_POSITION_PERCENT;
|
|
||||||
bg->mBackgroundFlags &= ~NS_STYLE_BG_Y_POSITION_LENGTH;
|
|
||||||
}
|
|
||||||
else if (eCSSUnit_Inherit == colorData.mBackPosition.mYValue.GetUnit()) {
|
|
||||||
canStoreInRuleTree = PR_FALSE;
|
|
||||||
bg->mBackgroundYPosition = parentBG->mBackgroundYPosition;
|
|
||||||
bg->mBackgroundFlags &= ~(NS_STYLE_BG_Y_POSITION_LENGTH | NS_STYLE_BG_Y_POSITION_PERCENT);
|
|
||||||
bg->mBackgroundFlags |= (parentFlags & (NS_STYLE_BG_Y_POSITION_LENGTH | NS_STYLE_BG_Y_POSITION_PERCENT));
|
|
||||||
}
|
|
||||||
else if (eCSSUnit_Initial == colorData.mBackPosition.mYValue.GetUnit()) {
|
|
||||||
bg->mBackgroundFlags &= ~(NS_STYLE_BG_Y_POSITION_LENGTH | NS_STYLE_BG_Y_POSITION_PERCENT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPUTE_END_RESET(Background, bg)
|
COMPUTE_END_RESET(Background, bg)
|
||||||
|
@ -5499,6 +5668,7 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
|
||||||
{
|
{
|
||||||
nsRuleDataColor colorData;
|
nsRuleDataColor colorData;
|
||||||
nsRuleDataMargin marginData;
|
nsRuleDataMargin marginData;
|
||||||
|
nsCSSValue firstBackgroundImage;
|
||||||
PRUint32 nValues = 0;
|
PRUint32 nValues = 0;
|
||||||
|
|
||||||
PRUint32 inheritBits = 0;
|
PRUint32 inheritBits = 0;
|
||||||
|
@ -5518,8 +5688,9 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
|
||||||
ruleData.mMarginData = &marginData;
|
ruleData.mMarginData = &marginData;
|
||||||
|
|
||||||
nsCSSValue* backgroundValues[] = {
|
nsCSSValue* backgroundValues[] = {
|
||||||
&colorData.mBackColor,
|
&colorData.mBackColor.mXValue,
|
||||||
&colorData.mBackImage
|
&colorData.mBackColor.mYValue,
|
||||||
|
&firstBackgroundImage
|
||||||
};
|
};
|
||||||
|
|
||||||
nsCSSValue* borderValues[] = {
|
nsCSSValue* borderValues[] = {
|
||||||
|
@ -5583,11 +5754,25 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
|
||||||
if (rule) {
|
if (rule) {
|
||||||
ruleData.mLevel = ruleNode->GetLevel();
|
ruleData.mLevel = ruleNode->GetLevel();
|
||||||
ruleData.mIsImportantRule = ruleNode->IsImportantRule();
|
ruleData.mIsImportantRule = ruleNode->IsImportantRule();
|
||||||
|
|
||||||
rule->MapRuleInfoInto(&ruleData);
|
rule->MapRuleInfoInto(&ruleData);
|
||||||
|
|
||||||
|
if ((ruleTypeMask & NS_AUTHOR_SPECIFIED_BACKGROUND) &&
|
||||||
|
colorData.mBackImage &&
|
||||||
|
firstBackgroundImage.GetUnit() == eCSSUnit_Null) {
|
||||||
|
// Handle background-image being a value list
|
||||||
|
firstBackgroundImage = colorData.mBackImage->mValue;
|
||||||
|
}
|
||||||
// Do the same nulling out as in GetBorderData, GetBackgroundData
|
// Do the same nulling out as in GetBorderData, GetBackgroundData
|
||||||
// or GetPaddingData.
|
// or GetPaddingData.
|
||||||
// We are sharing with some style rule. It really owns the data.
|
// We are sharing with some style rule. It really owns the data.
|
||||||
marginData.mBoxShadow = nsnull;
|
marginData.mBoxShadow = nsnull;
|
||||||
|
colorData.mBackImage = nsnull;
|
||||||
|
colorData.mBackRepeat = nsnull;
|
||||||
|
colorData.mBackAttachment = nsnull;
|
||||||
|
colorData.mBackPosition = nsnull;
|
||||||
|
colorData.mBackClip = nsnull;
|
||||||
|
colorData.mBackOrigin = nsnull;
|
||||||
|
|
||||||
if (ruleData.mLevel == nsStyleSet::eAgentSheet ||
|
if (ruleData.mLevel == nsStyleSet::eAgentSheet ||
|
||||||
ruleData.mLevel == nsStyleSet::eUserSheet) {
|
ruleData.mLevel == nsStyleSet::eUserSheet) {
|
||||||
|
|
|
@ -1207,28 +1207,44 @@ nsChangeHint nsStyleColor::MaxDifference()
|
||||||
//
|
//
|
||||||
|
|
||||||
nsStyleBackground::nsStyleBackground()
|
nsStyleBackground::nsStyleBackground()
|
||||||
: mBackgroundFlags(NS_STYLE_BG_IMAGE_NONE),
|
: mAttachmentCount(1)
|
||||||
mBackgroundAttachment(NS_STYLE_BG_ATTACHMENT_SCROLL),
|
, mClipCount(1)
|
||||||
mBackgroundClip(NS_STYLE_BG_CLIP_BORDER),
|
, mOriginCount(1)
|
||||||
mBackgroundInlinePolicy(NS_STYLE_BG_INLINE_POLICY_CONTINUOUS),
|
, mRepeatCount(1)
|
||||||
mBackgroundOrigin(NS_STYLE_BG_ORIGIN_PADDING),
|
, mPositionCount(1)
|
||||||
mBackgroundRepeat(NS_STYLE_BG_REPEAT_XY),
|
, mImageCount(1)
|
||||||
mBackgroundColor(NS_RGBA(0, 0, 0, 0))
|
, mBackgroundColor(NS_RGBA(0, 0, 0, 0))
|
||||||
|
, mFallbackBackgroundColor(NS_RGBA(0, 0, 0, 0))
|
||||||
|
, mBackgroundInlinePolicy(NS_STYLE_BG_INLINE_POLICY_CONTINUOUS)
|
||||||
{
|
{
|
||||||
|
Layer *onlyLayer = mLayers.AppendElement();
|
||||||
|
NS_ASSERTION(onlyLayer, "auto array must have room for 1 element");
|
||||||
|
onlyLayer->SetInitialValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource)
|
nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource)
|
||||||
: mBackgroundFlags(aSource.mBackgroundFlags),
|
: mAttachmentCount(aSource.mAttachmentCount)
|
||||||
mBackgroundAttachment(aSource.mBackgroundAttachment),
|
, mClipCount(aSource.mClipCount)
|
||||||
mBackgroundClip(aSource.mBackgroundClip),
|
, mOriginCount(aSource.mOriginCount)
|
||||||
mBackgroundInlinePolicy(aSource.mBackgroundInlinePolicy),
|
, mRepeatCount(aSource.mRepeatCount)
|
||||||
mBackgroundOrigin(aSource.mBackgroundOrigin),
|
, mPositionCount(aSource.mPositionCount)
|
||||||
mBackgroundRepeat(aSource.mBackgroundRepeat),
|
, mImageCount(aSource.mImageCount)
|
||||||
mBackgroundXPosition(aSource.mBackgroundXPosition),
|
, mLayers(aSource.mLayers) // deep copy
|
||||||
mBackgroundYPosition(aSource.mBackgroundYPosition),
|
, mBackgroundColor(aSource.mBackgroundColor)
|
||||||
mBackgroundColor(aSource.mBackgroundColor),
|
, mFallbackBackgroundColor(aSource.mFallbackBackgroundColor)
|
||||||
mBackgroundImage(aSource.mBackgroundImage)
|
, mBackgroundInlinePolicy(aSource.mBackgroundInlinePolicy)
|
||||||
{
|
{
|
||||||
|
// If the deep copy of mLayers failed, truncate the counts.
|
||||||
|
PRUint32 count = mLayers.Length();
|
||||||
|
if (count != aSource.mLayers.Length()) {
|
||||||
|
NS_WARNING("truncating counts due to out-of-memory");
|
||||||
|
mAttachmentCount = PR_MAX(mAttachmentCount, count);
|
||||||
|
mClipCount = PR_MAX(mClipCount, count);
|
||||||
|
mOriginCount = PR_MAX(mOriginCount, count);
|
||||||
|
mRepeatCount = PR_MAX(mRepeatCount, count);
|
||||||
|
mPositionCount = PR_MAX(mPositionCount, count);
|
||||||
|
mImageCount = PR_MAX(mImageCount, count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsStyleBackground::~nsStyleBackground()
|
nsStyleBackground::~nsStyleBackground()
|
||||||
|
@ -1237,24 +1253,19 @@ nsStyleBackground::~nsStyleBackground()
|
||||||
|
|
||||||
nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const
|
nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const
|
||||||
{
|
{
|
||||||
if ((mBackgroundAttachment == aOther.mBackgroundAttachment) &&
|
if (mBackgroundColor != aOther.mBackgroundColor ||
|
||||||
(mBackgroundFlags == aOther.mBackgroundFlags) &&
|
mFallbackBackgroundColor != aOther.mFallbackBackgroundColor ||
|
||||||
(mBackgroundRepeat == aOther.mBackgroundRepeat) &&
|
mBackgroundInlinePolicy != aOther.mBackgroundInlinePolicy ||
|
||||||
(mBackgroundColor == aOther.mBackgroundColor) &&
|
mImageCount != aOther.mImageCount)
|
||||||
(mBackgroundClip == aOther.mBackgroundClip) &&
|
return NS_STYLE_HINT_VISUAL;
|
||||||
(mBackgroundInlinePolicy == aOther.mBackgroundInlinePolicy) &&
|
|
||||||
(mBackgroundOrigin == aOther.mBackgroundOrigin) &&
|
// We checked the image count above.
|
||||||
EqualImages(mBackgroundImage, aOther.mBackgroundImage) &&
|
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, this) {
|
||||||
((!(mBackgroundFlags & NS_STYLE_BG_X_POSITION_PERCENT) ||
|
if (mLayers[i] != aOther.mLayers[i])
|
||||||
(mBackgroundXPosition.mFloat == aOther.mBackgroundXPosition.mFloat)) &&
|
return NS_STYLE_HINT_VISUAL;
|
||||||
(!(mBackgroundFlags & NS_STYLE_BG_X_POSITION_LENGTH) ||
|
}
|
||||||
(mBackgroundXPosition.mCoord == aOther.mBackgroundXPosition.mCoord))) &&
|
|
||||||
((!(mBackgroundFlags & NS_STYLE_BG_Y_POSITION_PERCENT) ||
|
return NS_STYLE_HINT_NONE;
|
||||||
(mBackgroundYPosition.mFloat == aOther.mBackgroundYPosition.mFloat)) &&
|
|
||||||
(!(mBackgroundFlags & NS_STYLE_BG_Y_POSITION_LENGTH) ||
|
|
||||||
(mBackgroundYPosition.mCoord == aOther.mBackgroundYPosition.mCoord))))
|
|
||||||
return NS_STYLE_HINT_NONE;
|
|
||||||
return NS_STYLE_HINT_VISUAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -1267,8 +1278,80 @@ nsChangeHint nsStyleBackground::MaxDifference()
|
||||||
|
|
||||||
PRBool nsStyleBackground::HasFixedBackground() const
|
PRBool nsStyleBackground::HasFixedBackground() const
|
||||||
{
|
{
|
||||||
return mBackgroundAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
|
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, this) {
|
||||||
mBackgroundImage;
|
const Layer &layer = mLayers[i];
|
||||||
|
if (layer.mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
|
||||||
|
layer.mImage.mRequest) {
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool nsStyleBackground::IsTransparent() const
|
||||||
|
{
|
||||||
|
return !BottomLayer().mImage.mRequest && mImageCount == 1 &&
|
||||||
|
NS_GET_A(mBackgroundColor) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsStyleBackground::Position::SetInitialValues()
|
||||||
|
{
|
||||||
|
mXPosition.mFloat = 0.0f;
|
||||||
|
mYPosition.mFloat = 0.0f;
|
||||||
|
mXIsPercent = PR_TRUE;
|
||||||
|
mYIsPercent = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize to initial values
|
||||||
|
nsStyleBackground::Image::Image()
|
||||||
|
{
|
||||||
|
SetInitialValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsStyleBackground::Image::~Image()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsStyleBackground::Image::SetInitialValues()
|
||||||
|
{
|
||||||
|
mRequest = nsnull;
|
||||||
|
mSpecified = PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool nsStyleBackground::Image::operator==(const Image& aOther) const
|
||||||
|
{
|
||||||
|
return mSpecified == aOther.mSpecified &&
|
||||||
|
EqualImages(mRequest, aOther.mRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsStyleBackground::Layer::Layer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
nsStyleBackground::Layer::~Layer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsStyleBackground::Layer::SetInitialValues()
|
||||||
|
{
|
||||||
|
mAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL;
|
||||||
|
mClip = NS_STYLE_BG_CLIP_BORDER;
|
||||||
|
mOrigin = NS_STYLE_BG_ORIGIN_PADDING;
|
||||||
|
mRepeat = NS_STYLE_BG_REPEAT_XY;
|
||||||
|
mPosition.SetInitialValues();
|
||||||
|
mImage.SetInitialValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool nsStyleBackground::Layer::operator==(const Layer& aOther) const
|
||||||
|
{
|
||||||
|
return mAttachment == aOther.mAttachment &&
|
||||||
|
mClip == aOther.mClip &&
|
||||||
|
mOrigin == aOther.mOrigin &&
|
||||||
|
mRepeat == aOther.mRepeat &&
|
||||||
|
mPosition == aOther.mPosition &&
|
||||||
|
mImage == aOther.mImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsCOMArray.h"
|
#include "nsCOMArray.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
#include "nsIAtom.h"
|
#include "nsIAtom.h"
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsCSSValue.h"
|
#include "nsCSSValue.h"
|
||||||
|
@ -164,30 +165,122 @@ struct nsStyleBackground {
|
||||||
static nsChangeHint MaxDifference();
|
static nsChangeHint MaxDifference();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PRUint8 mBackgroundFlags; // [reset] See nsStyleConsts.h
|
struct Position;
|
||||||
PRUint8 mBackgroundAttachment; // [reset] See nsStyleConsts.h
|
friend struct Position;
|
||||||
PRUint8 mBackgroundClip; // [reset] See nsStyleConsts.h
|
struct Position {
|
||||||
PRUint8 mBackgroundInlinePolicy; // [reset] See nsStyleConsts.h
|
typedef union {
|
||||||
PRUint8 mBackgroundOrigin; // [reset] See nsStyleConsts.h
|
nscoord mCoord; // for lengths
|
||||||
PRUint8 mBackgroundRepeat; // [reset] See nsStyleConsts.h
|
float mFloat; // for percents
|
||||||
|
} PositionCoord;
|
||||||
|
PositionCoord mXPosition, mYPosition;
|
||||||
|
PRPackedBool mXIsPercent, mYIsPercent;
|
||||||
|
|
||||||
// Note: a member of this union is valid IFF the appropriate bit flag
|
// Initialize nothing
|
||||||
// is set in mBackgroundFlags.
|
Position() {}
|
||||||
union {
|
|
||||||
nscoord mCoord;
|
// Initialize to initial values
|
||||||
float mFloat;
|
void SetInitialValues();
|
||||||
} mBackgroundXPosition, // [reset]
|
|
||||||
mBackgroundYPosition; // [reset]
|
PRBool operator==(const Position& aOther) const {
|
||||||
|
return mXIsPercent == aOther.mXIsPercent &&
|
||||||
|
(mXIsPercent ? (mXPosition.mFloat == aOther.mXPosition.mFloat)
|
||||||
|
: (mXPosition.mCoord == aOther.mXPosition.mCoord)) &&
|
||||||
|
mYIsPercent == aOther.mYIsPercent &&
|
||||||
|
(mYIsPercent ? (mYPosition.mFloat == aOther.mYPosition.mFloat)
|
||||||
|
: (mYPosition.mCoord == aOther.mYPosition.mCoord));
|
||||||
|
}
|
||||||
|
PRBool operator!=(const Position& aOther) const {
|
||||||
|
return !(*this == aOther);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We represent images as as struct because we need to distinguish the
|
||||||
|
* case where the imgIRequest is null because the winning
|
||||||
|
* background-image declaration specified no image from the case where
|
||||||
|
* the imgIRequest is null because the image that was specified was
|
||||||
|
* blocked or missing (e.g., missing file).
|
||||||
|
*/
|
||||||
|
struct Image;
|
||||||
|
friend struct Image;
|
||||||
|
struct Image {
|
||||||
|
nsCOMPtr<imgIRequest> mRequest;
|
||||||
|
PRBool mSpecified; // if false, mRequest is guaranteed to be null
|
||||||
|
|
||||||
|
// These are not inline so that we can avoid #include "imgIRequest.h"
|
||||||
|
|
||||||
|
// Initialize to initial values
|
||||||
|
Image();
|
||||||
|
~Image();
|
||||||
|
void SetInitialValues();
|
||||||
|
|
||||||
|
// An equality operator that compares the images using URL-equality
|
||||||
|
// rather than pointer-equality.
|
||||||
|
PRBool operator==(const Image& aOther) const;
|
||||||
|
PRBool operator!=(const Image& aOther) const {
|
||||||
|
return !(*this == aOther);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Layer;
|
||||||
|
friend struct Layer;
|
||||||
|
struct Layer {
|
||||||
|
PRUint8 mAttachment; // [reset] See nsStyleConsts.h
|
||||||
|
PRUint8 mClip; // [reset] See nsStyleConsts.h
|
||||||
|
PRUint8 mOrigin; // [reset] See nsStyleConsts.h
|
||||||
|
PRUint8 mRepeat; // [reset] See nsStyleConsts.h
|
||||||
|
Position mPosition; // [reset]
|
||||||
|
Image mImage; // [reset]
|
||||||
|
|
||||||
|
// Initializes only mImage
|
||||||
|
Layer();
|
||||||
|
~Layer();
|
||||||
|
|
||||||
|
void SetInitialValues();
|
||||||
|
|
||||||
|
// An equality operator that compares the images using URL-equality
|
||||||
|
// rather than pointer-equality.
|
||||||
|
PRBool operator==(const Layer& aOther) const;
|
||||||
|
PRBool operator!=(const Layer& aOther) const {
|
||||||
|
return !(*this == aOther);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// The (positive) number of computed values of each property, since
|
||||||
|
// the lengths of the lists are independent.
|
||||||
|
PRUint32 mAttachmentCount,
|
||||||
|
mClipCount,
|
||||||
|
mOriginCount,
|
||||||
|
mRepeatCount,
|
||||||
|
mPositionCount,
|
||||||
|
mImageCount;
|
||||||
|
// Layers are stored in an array, matching the top-to-bottom order in
|
||||||
|
// which they are specified in CSS. The number of layers to be used
|
||||||
|
// should come from the background-image property. We create
|
||||||
|
// additional |Layer| objects for *any* property, not just
|
||||||
|
// background-image. This means that the bottommost layer that
|
||||||
|
// callers in layout care about (which is also the one whose
|
||||||
|
// background-clip applies to the background-color) may not be last
|
||||||
|
// layer. In layers below the bottom layer, properties will be
|
||||||
|
// unitialized unless their count, above, indicates that they are
|
||||||
|
// present.
|
||||||
|
nsAutoTArray<Layer, 1> mLayers;
|
||||||
|
|
||||||
|
const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
|
||||||
|
|
||||||
|
#define NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(var_, stylebg_) \
|
||||||
|
for (PRUint32 var_ = (stylebg_)->mImageCount; var_-- != 0; )
|
||||||
|
|
||||||
nscolor mBackgroundColor; // [reset]
|
nscolor mBackgroundColor; // [reset]
|
||||||
nsCOMPtr<imgIRequest> mBackgroundImage; // [reset]
|
nscolor mFallbackBackgroundColor; // [reset]
|
||||||
|
|
||||||
|
// FIXME: This (now background-break in css3-background) should
|
||||||
|
// probably move into a different struct so that everything in
|
||||||
|
// nsStyleBackground is set by the background shorthand.
|
||||||
|
PRUint8 mBackgroundInlinePolicy; // [reset] See nsStyleConsts.h
|
||||||
|
|
||||||
// True if this background is completely transparent.
|
// True if this background is completely transparent.
|
||||||
PRBool IsTransparent() const
|
PRBool IsTransparent() const;
|
||||||
{
|
|
||||||
return (NS_GET_A(mBackgroundColor) == 0 &&
|
|
||||||
(mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE));
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have to take slower codepaths for fixed background attachment,
|
// We have to take slower codepaths for fixed background attachment,
|
||||||
// but we don't want to do that when there's no image.
|
// but we don't want to do that when there's no image.
|
||||||
|
|
|
@ -72,12 +72,17 @@ var gCSSProperties = {
|
||||||
invalid_values: []
|
invalid_values: []
|
||||||
},
|
},
|
||||||
"-moz-background-clip": {
|
"-moz-background-clip": {
|
||||||
|
/*
|
||||||
|
* When we rename this to 'background-clip', we also
|
||||||
|
* need to rename the values to match the spec.
|
||||||
|
*/
|
||||||
domProp: "MozBackgroundClip",
|
domProp: "MozBackgroundClip",
|
||||||
inherited: false,
|
inherited: false,
|
||||||
type: CSS_TYPE_LONGHAND,
|
type: CSS_TYPE_LONGHAND,
|
||||||
|
/* XXX Need to add support for "content" -- important for symmetry when handling background shorthand */
|
||||||
initial_values: [ "border" ],
|
initial_values: [ "border" ],
|
||||||
other_values: [ "padding" ],
|
other_values: [ "padding", "border, padding", "padding, padding, padding", "border, border" ],
|
||||||
invalid_values: [ "content", "margin" ]
|
invalid_values: [ "content", "margin", "border border" ]
|
||||||
},
|
},
|
||||||
"-moz-background-inline-policy": {
|
"-moz-background-inline-policy": {
|
||||||
domProp: "MozBackgroundInlinePolicy",
|
domProp: "MozBackgroundInlinePolicy",
|
||||||
|
@ -92,8 +97,8 @@ var gCSSProperties = {
|
||||||
inherited: false,
|
inherited: false,
|
||||||
type: CSS_TYPE_LONGHAND,
|
type: CSS_TYPE_LONGHAND,
|
||||||
initial_values: [ "padding" ],
|
initial_values: [ "padding" ],
|
||||||
other_values: [ "border", "content" ],
|
other_values: [ "border", "content", "border, padding", "padding, padding, padding", "border, border" ],
|
||||||
invalid_values: [ "margin" ]
|
invalid_values: [ "margin", "padding padding" ]
|
||||||
},
|
},
|
||||||
"-moz-binding": {
|
"-moz-binding": {
|
||||||
domProp: "MozBinding",
|
domProp: "MozBinding",
|
||||||
|
@ -608,14 +613,45 @@ var gCSSProperties = {
|
||||||
domProp: "background",
|
domProp: "background",
|
||||||
inherited: false,
|
inherited: false,
|
||||||
type: CSS_TYPE_TRUE_SHORTHAND,
|
type: CSS_TYPE_TRUE_SHORTHAND,
|
||||||
subproperties: [ "background-attachment", "background-color", "background-image", "background-position", "background-repeat", "-moz-background-clip", "-moz-background-inline-policy", "-moz-background-origin" ],
|
subproperties: [ "background-attachment", "background-color", "background-image", "background-position", "background-repeat", "-moz-background-clip", "-moz-background-origin" ],
|
||||||
initial_values: [ "transparent", "none", "repeat", "scroll", "0% 0%", "top left", "left top", "transparent none", "top left none", "left top none", "none left top", "none top left", "none 0% 0%", "transparent none repeat scroll top left", "left top repeat none scroll transparent"],
|
initial_values: [ "transparent", "none", "repeat", "scroll", "0% 0%", "top left", "left top", "transparent none", "top left none", "left top none", "none left top", "none top left", "none 0% 0%", "transparent none repeat scroll top left", "left top repeat none scroll transparent"],
|
||||||
other_values: [ "green", "none green repeat scroll left top", "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==)", "repeat url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==') transparent left top scroll", "repeat-x", "repeat-y", "no-repeat", "none repeat-y transparent scroll 0% 0%", "fixed", "0% top transparent fixed repeat none", "top", "left", "50% 50%", "center", "bottom right scroll none transparent repeat", "50% transparent", "transparent 50%", "50%" ],
|
other_values: [
|
||||||
|
/* without multiple backgrounds */
|
||||||
|
"green", "none green repeat scroll left top", "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==)", "repeat url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==') transparent left top scroll", "repeat-x", "repeat-y", "no-repeat", "none repeat-y transparent scroll 0% 0%", "fixed", "0% top transparent fixed repeat none", "top", "left", "50% 50%", "center", "bottom right scroll none transparent repeat", "50% transparent", "transparent 50%", "50%",
|
||||||
|
/* multiple backgrounds */
|
||||||
|
"url(404.png), url(404.png)",
|
||||||
|
"url(404.png), url(404.png) transparent",
|
||||||
|
"url(404.png), url(404.png) transparent red",
|
||||||
|
"repeat-x, fixed, none",
|
||||||
|
"0% top url(404.png), url(404.png) 0% top",
|
||||||
|
"fixed repeat-y top left url(404.png), repeat-x green",
|
||||||
|
/* test cases with clip+origin in the shorthand */
|
||||||
|
// This is commented out for now until we change
|
||||||
|
// -moz-background-clip to background-clip, -moz-background-origin
|
||||||
|
// to background-origin, change their value names to *-box, and add
|
||||||
|
// support for content-box on background-clip.
|
||||||
|
/*
|
||||||
|
"url(404.png) green padding-box",
|
||||||
|
"url(404.png) border-box transparent",
|
||||||
|
"content-box url(404.png) blue",
|
||||||
|
*/
|
||||||
|
],
|
||||||
invalid_values: [
|
invalid_values: [
|
||||||
/* mixes with keywords have to be in correct order */
|
/* mixes with keywords have to be in correct order */
|
||||||
"50% left", "top 50%",
|
"50% left", "top 50%",
|
||||||
/* bug 258080: don't accept background-position separated */
|
/* bug 258080: don't accept background-position separated */
|
||||||
"left url(404.png) top", "top url(404.png) left"
|
"left url(404.png) top", "top url(404.png) left",
|
||||||
|
/* not allowed to have color in non-bottom layer */
|
||||||
|
"url(404.png) transparent, url(404.png)",
|
||||||
|
"url(404.png) red, url(404.png)",
|
||||||
|
"url(404.png) transparent, url(404.png) transparent",
|
||||||
|
"url(404.png) transparent red, url(404.png) transparent red",
|
||||||
|
"url(404.png) red, url(404.png) red",
|
||||||
|
"url(404.png) rgba(0, 0, 0, 0), url(404.png)",
|
||||||
|
"url(404.png) rgb(255, 0, 0), url(404.png)",
|
||||||
|
"url(404.png) rgba(0, 0, 0, 0), url(404.png) rgba(0, 0, 0, 0)",
|
||||||
|
"url(404.png) rgba(0, 0, 0, 0) rgb(255, 0, 0), url(404.png) rgba(0, 0, 0, 0) rgb(255, 0, 0)",
|
||||||
|
"url(404.png) rgb(255, 0, 0), url(404.png) rgb(255, 0, 0)",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"background-attachment": {
|
"background-attachment": {
|
||||||
|
@ -623,15 +659,15 @@ var gCSSProperties = {
|
||||||
inherited: false,
|
inherited: false,
|
||||||
type: CSS_TYPE_LONGHAND,
|
type: CSS_TYPE_LONGHAND,
|
||||||
initial_values: [ "scroll" ],
|
initial_values: [ "scroll" ],
|
||||||
other_values: [ "fixed" ],
|
other_values: [ "fixed", "scroll,scroll", "fixed, scroll", "scroll, fixed, scroll", "fixed, fixed" ],
|
||||||
invalid_values: []
|
invalid_values: []
|
||||||
},
|
},
|
||||||
"background-color": {
|
"background-color": {
|
||||||
domProp: "backgroundColor",
|
domProp: "backgroundColor",
|
||||||
inherited: false,
|
inherited: false,
|
||||||
type: CSS_TYPE_LONGHAND,
|
type: CSS_TYPE_LONGHAND,
|
||||||
initial_values: [ "transparent", "rgba(255, 127, 15, 0)", "hsla(240, 97%, 50%, 0.0)", "rgba(0, 0, 0, 0)", "rgba(255,255,255,-3.7)" ],
|
initial_values: [ "transparent", "transparent transparent", "rgba(255, 127, 15, 0)", "hsla(240, 97%, 50%, 0.0)", "rgba(0, 0, 0, 0)", "rgba(255,255,255,-3.7)" ],
|
||||||
other_values: [ "green", "rgb(255, 0, 128)", "#fc2", "#96ed2a", "black", "rgba(255,255,0,3)" ],
|
other_values: [ "green", "rgb(255, 0, 128)", "#fc2", "#96ed2a", "black", "rgba(255,255,0,3)", "transparent green", "green transparent", "blue fuchsia", "rgb(3,4,5) hsl(240, 50%, 50%)" ],
|
||||||
invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "rgb(255.0,0.387,3489)" ]
|
invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "rgb(255.0,0.387,3489)" ]
|
||||||
},
|
},
|
||||||
"background-image": {
|
"background-image": {
|
||||||
|
@ -639,15 +675,22 @@ var gCSSProperties = {
|
||||||
inherited: false,
|
inherited: false,
|
||||||
type: CSS_TYPE_LONGHAND,
|
type: CSS_TYPE_LONGHAND,
|
||||||
initial_values: [ "none" ],
|
initial_values: [ "none" ],
|
||||||
other_values: [ "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==)", "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==')", 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==")', ],
|
other_values: [ "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==)", "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==')", 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==")',
|
||||||
|
"none, none",
|
||||||
|
"none, none, none, none, none",
|
||||||
|
"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==), none",
|
||||||
|
"none, url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==), none",
|
||||||
|
"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==), url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==)"
|
||||||
|
],
|
||||||
invalid_values: []
|
invalid_values: []
|
||||||
},
|
},
|
||||||
"background-position": {
|
"background-position": {
|
||||||
domProp: "backgroundPosition",
|
domProp: "backgroundPosition",
|
||||||
inherited: false,
|
inherited: false,
|
||||||
type: CSS_TYPE_LONGHAND,
|
type: CSS_TYPE_LONGHAND,
|
||||||
|
/* is "0px 0px" an initial value or not? */
|
||||||
initial_values: [ "top left", "left top", "0% 0%", "0% top", "left 0%" ],
|
initial_values: [ "top left", "left top", "0% 0%", "0% top", "left 0%" ],
|
||||||
other_values: [ "top", "left", "right", "bottom", "center", "center bottom", "bottom center", "center right", "right center", "center top", "top center", "center left", "left center", "right bottom", "bottom right", "50%" ],
|
other_values: [ "top", "left", "right", "bottom", "center", "center bottom", "bottom center", "center right", "right center", "center top", "top center", "center left", "left center", "right bottom", "bottom right", "50%", "top left, top left", "top left, top right", "top right, top left", "left top, 0% 0%", "10% 20%, 30%, 40%", "top left, bottom right", "right bottom, left top", "0%", "0px", "30px", "0%, 10%, 20%, 30%", "top, top, top, top, top" ],
|
||||||
invalid_values: [ "50% left", "top 50%" ]
|
invalid_values: [ "50% left", "top 50%" ]
|
||||||
},
|
},
|
||||||
"background-repeat": {
|
"background-repeat": {
|
||||||
|
@ -655,8 +698,13 @@ var gCSSProperties = {
|
||||||
inherited: false,
|
inherited: false,
|
||||||
type: CSS_TYPE_LONGHAND,
|
type: CSS_TYPE_LONGHAND,
|
||||||
initial_values: [ "repeat" ],
|
initial_values: [ "repeat" ],
|
||||||
other_values: [ "repeat-x", "repeat-y", "no-repeat" ],
|
other_values: [ "repeat-x", "repeat-y", "no-repeat",
|
||||||
invalid_values: []
|
"repeat-x, repeat-x",
|
||||||
|
"repeat, no-repeat",
|
||||||
|
"repeat-y, no-repeat, repeat-y",
|
||||||
|
"repeat, repeat, repeat"
|
||||||
|
],
|
||||||
|
invalid_values: [ "repeat repeat" ]
|
||||||
},
|
},
|
||||||
"border": {
|
"border": {
|
||||||
domProp: "border",
|
domProp: "border",
|
||||||
|
|
|
@ -106,14 +106,24 @@ is(e.style.font, "", "should not have font shorthand");
|
||||||
e.setAttribute("style", "font: medium serif; font-stretch: condensed");
|
e.setAttribute("style", "font: medium serif; font-stretch: condensed");
|
||||||
is(e.style.font, "", "should not have font shorthand");
|
is(e.style.font, "", "should not have font shorthand");
|
||||||
|
|
||||||
|
// For background, we can only express the value as a shorthand if
|
||||||
|
// origin and clip are both their default, or if they're both the same.
|
||||||
|
// ... or at least we will once we support them in the shorthand.
|
||||||
e.setAttribute("style", "background: red");
|
e.setAttribute("style", "background: red");
|
||||||
isnot(e.style.background, "", "should have background shorthand");
|
isnot(e.style.background, "", "should have background shorthand");
|
||||||
e.setAttribute("style", "background: red; -moz-background-origin: border");
|
e.setAttribute("style", "background: red; -moz-background-origin: border");
|
||||||
is(e.style.background, "", "should not have background shorthand");
|
is(e.style.background, "", "should not have background shorthand (origin:border)");
|
||||||
e.setAttribute("style", "background: red; -moz-background-clip: padding");
|
e.setAttribute("style", "background: red; -moz-background-clip: padding");
|
||||||
is(e.style.background, "", "should not have background shorthand");
|
is(e.style.background, "", "should not have background shorthand (clip:padding)");
|
||||||
|
e.setAttribute("style", "background: red; -moz-background-origin: content");
|
||||||
|
is(e.style.background, "", "should not have background shorthand (origin:content)");
|
||||||
|
// -moz-background-clip:content not yet supported
|
||||||
|
//e.setAttribute("style", "background: red; -moz-background-clip: content");
|
||||||
|
//is(e.style.background, "", "should not have background shorthand (clip:content)");
|
||||||
|
//e.setAttribute("style", "background: red; -moz-background-clip: content; -moz-background-origin: content;");
|
||||||
|
//isnot(e.style.background, "", "should have background shorthand (clip:content;origin:content)");
|
||||||
e.setAttribute("style", "background: red; -moz-background-inline-policy: each-box");
|
e.setAttribute("style", "background: red; -moz-background-inline-policy: each-box");
|
||||||
is(e.style.background, "", "should not have background shorthand");
|
isnot(e.style.background, "", "should have background shorthand (-moz-background-inline-policy not relevant)");
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
|
@ -197,7 +197,15 @@ inline PRBool
|
||||||
TableBackgroundPainter::TableBackgroundData::ShouldSetBCBorder()
|
TableBackgroundPainter::TableBackgroundData::ShouldSetBCBorder()
|
||||||
{
|
{
|
||||||
/* we only need accurate border data when positioning background images*/
|
/* we only need accurate border data when positioning background images*/
|
||||||
return mBackground && !(mBackground->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE);
|
if (!mBackground) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, mBackground) {
|
||||||
|
if (mBackground->mLayers[i].mImage.mRequest)
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -4114,7 +4114,9 @@ nsTreeBodyFrame::ScrollInternal(const ScrollParts& aParts, PRInt32 aRow)
|
||||||
// See if we have a transparent background or a background image.
|
// See if we have a transparent background or a background image.
|
||||||
// If we do, then we cannot blit.
|
// If we do, then we cannot blit.
|
||||||
const nsStyleBackground* background = GetStyleBackground();
|
const nsStyleBackground* background = GetStyleBackground();
|
||||||
if (background->mBackgroundImage || background->IsTransparent() ||
|
if (background->BottomLayer().mImage.mRequest ||
|
||||||
|
background->mImageCount > 1 ||
|
||||||
|
NS_GET_A(background->mBackgroundColor) < 255 ||
|
||||||
PR_ABS(delta)*mRowHeight >= mRect.height) {
|
PR_ABS(delta)*mRowHeight >= mRect.height) {
|
||||||
Invalidate();
|
Invalidate();
|
||||||
} else {
|
} else {
|
||||||
|
@ -4149,9 +4151,12 @@ nsTreeBodyFrame::ScrollHorzInternal(const ScrollParts& aParts, PRInt32 aPosition
|
||||||
PRInt32 delta = aPosition - mHorzPosition;
|
PRInt32 delta = aPosition - mHorzPosition;
|
||||||
mHorzPosition = aPosition;
|
mHorzPosition = aPosition;
|
||||||
|
|
||||||
// See if we have a background image. If we do, then we cannot blit.
|
// See if we have a transparent background or a background image.
|
||||||
|
// If we do, then we cannot blit.
|
||||||
const nsStyleBackground* background = GetStyleBackground();
|
const nsStyleBackground* background = GetStyleBackground();
|
||||||
if (background->mBackgroundImage || background->IsTransparent() ||
|
if (background->BottomLayer().mImage.mRequest ||
|
||||||
|
background->mImageCount > 1 ||
|
||||||
|
NS_GET_A(background->mBackgroundColor) < 255 ||
|
||||||
PR_ABS(delta) >= mRect.width) {
|
PR_ABS(delta) >= mRect.width) {
|
||||||
Invalidate();
|
Invalidate();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -685,6 +685,20 @@ class nsTArray : public nsTArray_base {
|
||||||
RemoveElementsAt(newLen, oldLen - newLen);
|
RemoveElementsAt(newLen, oldLen - newLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This method ensures that the array has length at least the given
|
||||||
|
// length. If the current length is shorter than the given length,
|
||||||
|
// then new elements will be constructed using elem_type's default
|
||||||
|
// constructor.
|
||||||
|
// @param minLen The desired minimum length of this array.
|
||||||
|
// @return True if the operation succeeded; false otherwise.
|
||||||
|
PRBool EnsureLengthAtLeast(size_type minLen) {
|
||||||
|
size_type oldLen = Length();
|
||||||
|
if (minLen > oldLen) {
|
||||||
|
return InsertElementsAt(oldLen, minLen - oldLen) != nsnull;
|
||||||
|
}
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// This method inserts elements into the array, constructing
|
// This method inserts elements into the array, constructing
|
||||||
// them using elem_type's default constructor.
|
// them using elem_type's default constructor.
|
||||||
// @param index the place to insert the new elements. This must be no
|
// @param index the place to insert the new elements. This must be no
|
||||||
|
|