diff --git a/mozilla/content/html/style/src/Makefile.in b/mozilla/content/html/style/src/Makefile.in
index 7b3a1d835f9..36869ea1720 100644
--- a/mozilla/content/html/style/src/Makefile.in
+++ b/mozilla/content/html/style/src/Makefile.in
@@ -47,6 +47,7 @@ REQUIRES = xpcom \
xuldoc \
xpconnect \
pref \
+ view \
$(NULL)
CPPSRCS = \
diff --git a/mozilla/content/html/style/src/makefile.win b/mozilla/content/html/style/src/makefile.win
index d34deb13084..8431dda1e1b 100644
--- a/mozilla/content/html/style/src/makefile.win
+++ b/mozilla/content/html/style/src/makefile.win
@@ -41,6 +41,7 @@ REQUIRES = xpcom \
layout \
gfx \
content_xul \
+ view \
$(NULL)
DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
diff --git a/mozilla/content/html/style/src/nsComputedDOMStyle.cpp b/mozilla/content/html/style/src/nsComputedDOMStyle.cpp
index aad4a013518..20879fdefe8 100644
--- a/mozilla/content/html/style/src/nsComputedDOMStyle.cpp
+++ b/mozilla/content/html/style/src/nsComputedDOMStyle.cpp
@@ -41,6 +41,8 @@
#include "nsIPresContext.h"
#include "nsIContent.h"
#include "nsIFrame.h"
+#include "nsIScrollableFrame.h"
+#include "nsLayoutAtoms.h"
#include "nsIDOMElement.h"
#include "nsIStyleContext.h"
#include "nsROCSSPrimitiveValue.h"
@@ -82,20 +84,31 @@ public:
private:
//Helpers
- nsresult GetAbsoluteFrameRect(nsIFrame *aFrame, nsRect& aRect);
+ nsresult GetOffsetWidthFor(PRUint8 aSide, nsIFrame *aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue);
+ nsresult GetAbsoluteOffset(PRUint8 aSide, nsIFrame *aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue);
+ nsresult GetRelativeOffset(PRUint8 aSide, nsIFrame *aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue);
+ nsresult GetStaticOffset(PRUint8 aSide, nsIFrame *aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue);
+ nsIFrame* GetContainingBlock(nsIFrame *aFrame);
nsresult GetStyleData(nsStyleStructID aID,
const nsStyleStruct*& aStyleStruct,
nsIFrame* aFrame=0);
nsresult GetPaddingWidthFor(PRUint8 aSide, nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue);
+ nscoord GetPaddingWidthCoordFor(PRUint8 aSide, nsIFrame *aFrame);
nsresult GetBorderStyleFor(PRUint8 aSide, nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue);
nsresult GetBorderWidthFor(PRUint8 aSide, nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue);
+ nscoord GetBorderWidthCoordFor(PRUint8 aSide, nsIFrame *aFrame);
nsresult GetBorderColorFor(PRUint8 aSide, nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue);
nsresult GetMarginWidthFor(PRUint8 aSide, nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue);
+ nscoord GetMarginWidthCoordFor(PRUint8 aSide, nsIFrame *aFrame);
// Properties
nsresult GetWidth(nsIFrame *aFrame, nsIDOMCSSPrimitiveValue*& aValue);
@@ -205,7 +218,7 @@ private:
nsCOMPtr mContent;
// When a frame is unavailable strong reference to the
// style context while we're accessing the data from in.
- nsCOMPtr mStyleContextHolder;
+ nsCOMPtr mStyleContextHolder;
nsCOMPtr mPseudo;
float mT2P; // For unit conversions
@@ -830,16 +843,7 @@ nsresult
nsComputedDOMStyle::GetBottom(nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue)
{
- nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
- NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
-
- nsRect rect;
- GetAbsoluteFrameRect(aFrame, rect);
-
- val->SetTwips(rect.y + rect.height);
-
- return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
- (void **)&aValue);
+ return GetOffsetWidthFor(NS_SIDE_BOTTOM, aFrame, aValue);
}
@@ -1371,18 +1375,21 @@ nsComputedDOMStyle::GetZIndex(nsIFrame *aFrame,
const nsStylePosition* position = nsnull;
nsAutoString zindex;
- do {
- GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position,
- aFrame);
-
- if(position){
- if(position->mZIndex.GetUnit()==eStyleUnit_Integer) {
- zindex.AppendInt(position->mZIndex.GetIntValue(), 10);
- break;
- }
+ GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position, aFrame);
+ while (position) {
+ if (position->mZIndex.GetUnit() == eStyleUnit_Integer) {
+ zindex.AppendInt(position->mZIndex.GetIntValue(), 10);
+ break;
+ }
+ if (aFrame) {
aFrame->GetParent(&aFrame);
}
- }while(aFrame && position);
+ if (aFrame) {
+ aFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position);
+ } else {
+ position = nsnull;
+ }
+ }
val->SetString(zindex);
@@ -1696,11 +1703,48 @@ nsComputedDOMStyle::GetHeight(nsIFrame *aFrame,
nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
- nsRect rect;
- GetAbsoluteFrameRect(aFrame, rect);
-
- val->SetTwips(rect.height);
+ if (aFrame) {
+ // Flush all pending notifications so that our frames are up to date
+ nsCOMPtr document;
+ mContent->GetDocument(*getter_AddRefs(document));
+ if (document) {
+ document->FlushPendingNotifications();
+ }
+
+ const nsStyleDisplay* displayData = nsnull;
+ GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)displayData, aFrame);
+ if (displayData && displayData->mDisplay == NS_STYLE_DISPLAY_INLINE) {
+ nsFrameState frameState;
+ aFrame->GetFrameState(&frameState);
+ if (! (frameState & NS_FRAME_REPLACED_ELEMENT)) {
+ // XXX no useful height we can give for non-replaced inlines yet
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+ }
+
+ nsRect rect;
+ nsMargin padding;
+ nsMargin border;
+ aFrame->GetRect(rect);
+ const nsStylePadding* paddingData=nsnull;
+ GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)paddingData, aFrame);
+ if (paddingData) {
+ paddingData->CalcPaddingFor(aFrame, padding);
+ }
+ const nsStyleBorder* borderData=nsnull;
+ GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData, aFrame);
+ if (borderData) {
+ borderData->CalcBorderFor(aFrame, border);
+ }
+
+ val->SetTwips(rect.height - padding.top - padding.bottom -
+ border.top - border.bottom);
+ } else {
+ // XXX no frame. This property makes no sense in this case
+ val->SetTwips(0);
+ }
+
return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
(void **)&aValue);
}
@@ -1709,16 +1753,7 @@ nsresult
nsComputedDOMStyle::GetLeft(nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue)
{
- nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
- NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
-
- nsRect rect;
- GetAbsoluteFrameRect(aFrame, rect);
-
- val->SetTwips(rect.x);
-
- return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
- (void **)&aValue);
+ return GetOffsetWidthFor(NS_SIDE_LEFT, aFrame, aValue);
}
#if 0
@@ -1977,16 +2012,7 @@ nsresult
nsComputedDOMStyle::GetRight(nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue)
{
- nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
- NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
-
- nsRect rect;
- GetAbsoluteFrameRect(aFrame, rect);
-
- val->SetTwips(rect.x + rect.width);
-
- return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
- (void **)&aValue);
+ return GetOffsetWidthFor(NS_SIDE_RIGHT, aFrame, aValue);
}
#if 0
@@ -2073,16 +2099,7 @@ nsresult
nsComputedDOMStyle::GetTop(nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue)
{
- nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
- NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
-
- nsRect rect;
- GetAbsoluteFrameRect(aFrame, rect);
-
- val->SetTwips(rect.y);
-
- return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
- (void **)&aValue);
+ return GetOffsetWidthFor(NS_SIDE_TOP, aFrame, aValue);
}
#if 0
@@ -2142,85 +2159,297 @@ nsComputedDOMStyle::GetROCSSPrimitiveValue()
}
nsresult
-nsComputedDOMStyle::GetAbsoluteFrameRect(nsIFrame *aFrame, nsRect& aRect)
+nsComputedDOMStyle::GetOffsetWidthFor(PRUint8 aSide, nsIFrame* aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue)
{
- nsresult res = NS_OK;
+ const nsStyleDisplay* display = nsnull;
+ GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display, aFrame);
- aRect.x = aRect.y = 0;
- aRect.Empty();
-
- if (!aFrame) {
- return NS_OK;
- }
-
- // Flush all pending notifications so that our frames are uptodate
+ // Flush all pending notifications so that our frames are up to date
nsCOMPtr document;
mContent->GetDocument(*getter_AddRefs(document));
-
if (document) {
document->FlushPendingNotifications();
}
- // Get the union of all rectangles in this and continuation frames
- nsIFrame* next = aFrame;
- do {
- nsRect rect;
- next->GetRect(rect);
- aRect.UnionRect(aRect, rect);
- next->GetNextInFlow(&next);
- } while (nsnull != next);
-
- nsIFrame* frame = aFrame;
- nsPoint origin(0, 0), tmp(0, 0);
- nsFrameState position;
- do {
- frame->GetOrigin(tmp);
- origin += tmp;
-
- frame->GetFrameState(&position);
- if(position & NS_FRAME_OUT_OF_FLOW) {
- break; // Do not include parent if absolutely positioned - Bug 49942
- }
- // Add the parent's origin to our own to
- // get to the right coordinate system
- frame->GetParent(&frame);
- } while(frame);
-
- // For the origin, add in the border for the frame
- const nsStyleBorder* border;
- const nsStylePadding* padding;
- nsStyleCoord coord;
- GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)border, aFrame);
- GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)padding, aFrame);
- if (border && padding) {
- if (eStyleUnit_Coord == border->mBorder.GetLeftUnit()) {
- origin.x += border->mBorder.GetLeft(coord).GetCoordValue();
- aRect.width -= border->mBorder.GetLeft(coord).GetCoordValue();
- //aRect.width -= margin->mMargin.GetLeft(coord).GetCoordValue();
- aRect.width -= padding->mPadding.GetLeft(coord).GetCoordValue();
- }
- if (eStyleUnit_Coord == border->mBorder.GetTopUnit()) {
- origin.y += border->mBorder.GetTop(coord).GetCoordValue();
- aRect.height -= border->mBorder.GetTop(coord).GetCoordValue();
- //aRect.height -= margin->mMargin.GetTop(coord).GetCoordValue();
- aRect.height -= padding->mPadding.GetTop(coord).GetCoordValue();
- }
- if (eStyleUnit_Coord == border->mBorder.GetRightUnit()) {
- aRect.width -= border->mBorder.GetRight(coord).GetCoordValue();
- //aRect.width -= margin->mMargin.GetRight(coord).GetCoordValue();
- aRect.width -= padding->mPadding.GetRight(coord).GetCoordValue();
- }
- if (eStyleUnit_Coord == border->mBorder.GetBottomUnit()) {
- aRect.height -= border->mBorder.GetBottom(coord).GetCoordValue();
- //aRect.height -= margin->mMargin.GetBottom(coord).GetCoordValue();
- aRect.height -= padding->mPadding.GetBottom(coord).GetCoordValue();
+ nsresult rv = NS_OK;
+ if (display) {
+ switch (display->mPosition) {
+ case NS_STYLE_POSITION_NORMAL:
+ rv = GetStaticOffset(aSide, aFrame, aValue);
+ break;
+ case NS_STYLE_POSITION_RELATIVE:
+ rv = GetRelativeOffset(aSide, aFrame, aValue);
+ break;
+ case NS_STYLE_POSITION_ABSOLUTE:
+ case NS_STYLE_POSITION_FIXED:
+ rv = GetAbsoluteOffset(aSide, aFrame, aValue);
+ break;
+ default:
+ NS_WARNING("double check the position");
+ break;
}
}
- aRect.x = origin.x;
- aRect.y = origin.y;
+ return rv;
+}
- return res;
+nsresult
+nsComputedDOMStyle::GetAbsoluteOffset(PRUint8 aSide, nsIFrame* aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue)
+{
+ nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
+ NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
+
+ nsIFrame* container = GetContainingBlock(aFrame);
+ if (container) {
+ nsRect rect;
+ nsRect containerRect;
+ nscoord margin = GetMarginWidthCoordFor(aSide, aFrame);
+ nscoord border = GetBorderWidthCoordFor(aSide, container);
+ nscoord horScrollBarHeight = 0;
+ nscoord verScrollBarWidth = 0;
+ aFrame->GetRect(rect);
+ container->GetRect(containerRect);
+
+ nsCOMPtr typeAtom;
+ container->GetFrameType(getter_AddRefs(typeAtom));
+ if (typeAtom == nsLayoutAtoms::viewportFrame) {
+ // For absolutely positioned frames scrollbars are taken into
+ // account by virtue of getting a containing block that does
+ // _not_ include the scrollbars. For fixed positioned frames,
+ // the containing block is the viewport, which _does_ include
+ // scrollbars. We have to do some extra work.
+ nsIFrame* scrollingChild;
+ nsCOMPtr presShell = do_QueryReferent(mPresShellWeak);
+ NS_ASSERTION(presShell, "Must have a presshell!");
+ nsCOMPtr presContext;
+ presShell->GetPresContext(getter_AddRefs(presContext));
+ // the first child in the default frame list is what we want
+ container->FirstChild(presContext, nsnull, &scrollingChild);
+ nsCOMPtr scrollFrame(do_QueryInterface(scrollingChild));
+ if (scrollFrame) {
+ scrollFrame->GetScrollbarSizes(presContext, &verScrollBarWidth,
+ &horScrollBarHeight);
+ PRBool verScrollBarVisible;
+ PRBool horScrollBarVisible;
+ scrollFrame->GetScrollbarVisibility(presContext, &verScrollBarVisible,
+ &horScrollBarVisible);
+ if (!verScrollBarVisible) {
+ verScrollBarWidth = 0;
+ }
+ if (!horScrollBarVisible) {
+ horScrollBarHeight = 0;
+ }
+ }
+ }
+ nscoord offset = 0;
+ switch (aSide) {
+ case NS_SIDE_TOP:
+ offset = rect.y - margin - border;
+ break;
+ case NS_SIDE_RIGHT:
+ offset = containerRect.width - rect.width -
+ rect.x - margin - border - verScrollBarWidth;
+ break;
+ case NS_SIDE_BOTTOM:
+ offset = containerRect.height - rect.height -
+ rect.y - margin - border - horScrollBarHeight;
+ break;
+ case NS_SIDE_LEFT:
+ offset = rect.x - margin - border;
+ break;
+ default:
+ NS_WARNING("double check the side");
+ break;
+ }
+ val->SetTwips(offset);
+ } else {
+ // XXX no frame. This property makes no sense
+ val->SetTwips(0);
+ }
+
+ return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
+ (void **)&aValue);
+}
+
+nsresult
+nsComputedDOMStyle::GetRelativeOffset(PRUint8 aSide, nsIFrame* aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue)
+{
+ nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
+ NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
+
+ const nsStylePosition* positionData = nsnull;
+ GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)positionData, aFrame);
+ if (positionData) {
+ nsStyleCoord coord;
+ PRInt32 sign = 1;
+ switch (aSide) {
+ case NS_SIDE_TOP:
+ positionData->mOffset.GetTop(coord);
+ if (coord.GetUnit() != eStyleUnit_Coord &&
+ coord.GetUnit() != eStyleUnit_Percent) {
+ positionData->mOffset.GetBottom(coord);
+ sign = -1;
+ }
+ break;
+ case NS_SIDE_RIGHT:
+ positionData->mOffset.GetRight(coord);
+ if (coord.GetUnit() != eStyleUnit_Coord &&
+ coord.GetUnit() != eStyleUnit_Percent) {
+ positionData->mOffset.GetLeft(coord);
+ sign = -1;
+ }
+ break;
+ case NS_SIDE_BOTTOM:
+ positionData->mOffset.GetBottom(coord);
+ if (coord.GetUnit() != eStyleUnit_Coord &&
+ coord.GetUnit() != eStyleUnit_Percent) {
+ positionData->mOffset.GetTop(coord);
+ sign = -1;
+ }
+ break;
+ case NS_SIDE_LEFT:
+ positionData->mOffset.GetLeft(coord);
+ if (coord.GetUnit() != eStyleUnit_Coord &&
+ coord.GetUnit() != eStyleUnit_Percent) {
+ positionData->mOffset.GetRight(coord);
+ sign = -1;
+ }
+ break;
+ default:
+ NS_WARNING("double check the side");
+ break;
+ }
+
+ nsIFrame* container = nsnull;
+ const nsStyleBorder* borderData = nsnull;
+ const nsStylePadding* paddingData = nsnull;
+ nsMargin border;
+ nsMargin padding;
+ nsRect rect;
+ switch(coord.GetUnit()) {
+ case eStyleUnit_Coord:
+ val->SetTwips(sign * coord.GetCoordValue());
+ break;
+ case eStyleUnit_Percent:
+ container = GetContainingBlock(aFrame);
+ if (container) {
+ container->GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData);
+ if (borderData) {
+ borderData->CalcBorderFor(container, border);
+ }
+ container->GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)paddingData);
+ if (paddingData) {
+ paddingData->CalcPaddingFor(container, padding);
+ }
+ container->GetRect(rect);
+ if (aSide == NS_SIDE_LEFT || aSide == NS_SIDE_RIGHT) {
+ val->SetTwips(sign * coord.GetPercentValue() *
+ (rect.width - border.left - border.right -
+ padding.left - padding.right));
+ } else {
+ val->SetTwips(sign * coord.GetPercentValue() *
+ (rect.height - border.top - border.bottom -
+ padding.top - padding.bottom));
+ }
+ } else {
+ // XXX no containing block.
+ val->SetTwips(0);
+ }
+ break;
+ default:
+ NS_WARNING("double check the unit");
+ val->SetTwips(0);
+ break;
+ }
+ }
+
+ return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
+ (void **)&aValue);
+}
+
+nsresult
+nsComputedDOMStyle::GetStaticOffset(PRUint8 aSide, nsIFrame* aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue)
+
+{
+ /*
+ This does not work correctly yet. Specifically, we _always_
+ return computed values here. This needs to be worked on.
+ */
+ return NS_ERROR_NOT_IMPLEMENTED;
+#if 0
+ nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
+ NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
+
+ const nsStylePosition* positionData = nsnull;
+ GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)positionData, aFrame);
+ if (positionData) {
+ nsStyleCoord coord;
+ switch (aSide) {
+ case NS_SIDE_TOP:
+ positionData->mOffset.GetTop(coord);
+ break;
+ case NS_SIDE_RIGHT:
+ positionData->mOffset.GetRight(coord);
+ break;
+ case NS_SIDE_BOTTOM:
+ positionData->mOffset.GetBottom(coord);
+ break;
+ case NS_SIDE_LEFT:
+ positionData->mOffset.GetLeft(coord);
+ break;
+ default:
+ NS_WARNING("double check the side");
+ break;
+ }
+
+ char buf[16];
+ PRInt32 len;
+ switch(coord.GetUnit()) {
+ case eStyleUnit_Coord:
+ val->SetTwips(coord.GetCoordValue());
+ break;
+ case eStyleUnit_Percent:
+ len = PR_snprintf(buf, sizeof(buf), "%d%%",
+ int(coord.GetPercentValue() * 100.0));
+ val->SetString(buf);
+ break;
+ default:
+ NS_WARNING("double check the unit");
+ val->SetTwips(0);
+ break;
+ }
+ }
+
+ return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
+ (void **)&aValue);
+#endif
+}
+
+
+nsIFrame*
+nsComputedDOMStyle::GetContainingBlock(nsIFrame *aFrame)
+{
+ if (!aFrame) {
+ // Tell caller that they have no containing block, seeing as they
+ // are not being displayed
+ return nsnull;
+ }
+ nsIFrame* container = aFrame;
+ PRBool done = PR_FALSE;
+ do {
+ container->GetParent(&container);
+ if (container) {
+ (container)->IsPercentageBase(done);
+ }
+ } while (!done && container);
+
+ NS_POSTCONDITION(container, "Frame has no containing block");
+
+ return container;
}
nsresult
@@ -2231,7 +2460,9 @@ nsComputedDOMStyle::GetStyleData(nsStyleStructID aID,
if(aFrame && !mPseudo) {
aFrame->GetStyleData(aID, aStyleStruct);
}
- else {
+ else if (mStyleContextHolder) {
+ aStyleStruct = mStyleContextHolder->GetStyleData(aID);
+ } else {
nsCOMPtr presShell=do_QueryReferent(mPresShellWeak);
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
@@ -2254,6 +2485,7 @@ nsComputedDOMStyle::GetStyleData(nsStyleStructID aID,
mStyleContextHolder=sctx;
}
}
+ NS_ASSERTION(aStyleStruct, "Failed to get a style struct");
return NS_OK;
}
@@ -2264,50 +2496,79 @@ nsComputedDOMStyle::GetPaddingWidthFor(PRUint8 aSide,
{
nsROCSSPrimitiveValue* val=GetROCSSPrimitiveValue();
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
-
- const nsStylePadding* padding=nsnull;
- GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)padding, aFrame);
-
- if(padding) {
- nsStyleCoord coord;
- switch(aSide) {
- case NS_SIDE_TOP:
- padding->mPadding.GetTop(coord); break;
- case NS_SIDE_BOTTOM :
- padding->mPadding.GetBottom(coord); break;
- case NS_SIDE_LEFT :
- padding->mPadding.GetLeft(coord); break;
- case NS_SIDE_RIGHT :
- padding->mPadding.GetRight(coord); break;
- default:
- NS_WARNING("double check the side");
- break;
- }
-
- switch(coord.GetUnit()) {
- case eStyleUnit_Coord:
- val->SetTwips(coord.GetCoordValue()); break;
- case eStyleUnit_Percent:
- {
- nsIFrame* parent=nsnull;
- aFrame->GetParent(&parent);
- if(parent) {
- nsRect rect;
- parent->GetRect(rect);
- val->SetTwips(nscoord(coord.GetPercentValue() * rect.width));
- break; // intentionally breaking here...
- }
- }
- default:
- NS_WARNING("double check the unit");
- break;
- }
- }
+
+ nscoord width = GetPaddingWidthCoordFor(aSide, aFrame);
+ val->SetTwips(width);
return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
(void **)&aValue);
}
+nscoord
+nsComputedDOMStyle::GetPaddingWidthCoordFor(PRUint8 aSide, nsIFrame* aFrame)
+{
+ const nsStylePadding* paddingData=nsnull;
+ GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)paddingData, aFrame);
+
+ if(paddingData) {
+ nsMargin padding;
+ paddingData->CalcPaddingFor(aFrame, padding);
+ switch(aSide) {
+ case NS_SIDE_TOP :
+ return padding.top;
+ break;
+ case NS_SIDE_BOTTOM :
+ return padding.bottom;
+ break;
+ case NS_SIDE_LEFT :
+ return padding.left;
+ break;
+ case NS_SIDE_RIGHT :
+ return padding.right;
+ break;
+ default:
+ NS_WARNING("double check the side");
+ break;
+ }
+ }
+
+ return 0;
+}
+
+nscoord
+nsComputedDOMStyle::GetBorderWidthCoordFor(PRUint8 aSide, nsIFrame *aFrame)
+{
+ nsROCSSPrimitiveValue* val=GetROCSSPrimitiveValue();
+ NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
+
+ const nsStyleBorder* borderData = nsnull;
+ GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData, aFrame);
+
+ if(borderData) {
+ nsMargin border;
+ borderData->CalcBorderFor(aFrame, border);
+ switch(aSide) {
+ case NS_SIDE_TOP :
+ return border.top;
+ break;
+ case NS_SIDE_BOTTOM :
+ return border.bottom;
+ break;
+ case NS_SIDE_LEFT :
+ return border.left;
+ break;
+ case NS_SIDE_RIGHT :
+ return border.right;
+ break;
+ default:
+ NS_WARNING("double check the side");
+ break;
+ }
+ }
+
+ return 0;
+}
+
nsresult
nsComputedDOMStyle::GetBorderWidthFor(PRUint8 aSide,
nsIFrame *aFrame,
@@ -2407,47 +2668,42 @@ nsComputedDOMStyle::GetMarginWidthFor(PRUint8 aSide,
nsROCSSPrimitiveValue* val=GetROCSSPrimitiveValue();
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
- const nsStyleMargin* margin=nsnull;
- GetStyleData(eStyleStruct_Margin, (const nsStyleStruct*&)margin, aFrame);
+ nscoord width = GetMarginWidthCoordFor(aSide, aFrame);
+ val->SetTwips(width);
- if(margin) {
- nsStyleCoord coord;
+ return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
+ (void **)&aValue);
+}
+
+nscoord
+nsComputedDOMStyle::GetMarginWidthCoordFor(PRUint8 aSide,
+ nsIFrame *aFrame)
+{
+ const nsStyleMargin* marginData=nsnull;
+ GetStyleData(eStyleStruct_Margin, (const nsStyleStruct*&)marginData, aFrame);
+ if(marginData) {
+ nsMargin margin;
+ marginData->CalcMarginFor(aFrame, margin);
switch(aSide) {
case NS_SIDE_TOP :
- margin->mMargin.GetTop(coord); break;
+ return margin.top;
+ break;
case NS_SIDE_BOTTOM :
- margin->mMargin.GetBottom(coord); break;
+ return margin.bottom;
+ break;
case NS_SIDE_LEFT :
- margin->mMargin.GetLeft(coord); break;
+ return margin.left;
+ break;
case NS_SIDE_RIGHT :
- margin->mMargin.GetRight(coord); break;
+ return margin.right;
+ break;
default:
NS_WARNING("double check the side");
break;
}
-
- switch(coord.GetUnit()) {
- case eStyleUnit_Coord:
- val->SetTwips(coord.GetCoordValue()); break;
- case eStyleUnit_Percent:
- {
- nsIFrame* parent=nsnull;
- aFrame->GetParent(&parent);
- if(parent) {
- nsRect rect;
- parent->GetRect(rect);
- val->SetTwips(nscoord(coord.GetPercentValue() * rect.width));
- break; // intentionally breaking here...
- }
- }
- default:
- NS_WARNING("double check the unit");
- break;
- }
}
- return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
- (void **)&aValue);
+ return 0;
}
nsresult
@@ -2482,10 +2738,46 @@ nsComputedDOMStyle::GetWidth(nsIFrame *aFrame,
nsROCSSPrimitiveValue* val=GetROCSSPrimitiveValue();
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
- nsRect rect;
- GetAbsoluteFrameRect(aFrame, rect);
-
- val->SetTwips(rect.width);
+ if (aFrame) {
+ // Flush all pending notifications so that our frames are up to date
+ nsCOMPtr document;
+ mContent->GetDocument(*getter_AddRefs(document));
+
+ if (document) {
+ document->FlushPendingNotifications();
+ }
+
+ const nsStyleDisplay* displayData = nsnull;
+ GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)displayData, aFrame);
+ if (displayData && displayData->mDisplay == NS_STYLE_DISPLAY_INLINE) {
+ nsFrameState frameState;
+ aFrame->GetFrameState(&frameState);
+ if (! (frameState & NS_FRAME_REPLACED_ELEMENT)) {
+ // XXX no useful width we can give for non-replaced inlines yet
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+ }
+
+ nsRect rect;
+ nsMargin padding;
+ nsMargin border;
+ aFrame->GetRect(rect);
+ const nsStylePadding* paddingData=nsnull;
+ GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)paddingData, aFrame);
+ if (paddingData) {
+ paddingData->CalcPaddingFor(aFrame, padding);
+ }
+ const nsStyleBorder* borderData=nsnull;
+ GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData, aFrame);
+ if (borderData) {
+ borderData->CalcBorderFor(aFrame, border);
+ }
+ val->SetTwips(rect.width - padding.left - padding.right -
+ border.left - border.right);
+ } else {
+ // XXX no frame. This property makes no sense in this case
+ val->SetTwips(0);
+ }
return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
(void **)&aValue);
diff --git a/mozilla/content/shared/src/nsStyleStruct.cpp b/mozilla/content/shared/src/nsStyleStruct.cpp
index 81f15c90aed..9263ad5fd46 100644
--- a/mozilla/content/shared/src/nsStyleStruct.cpp
+++ b/mozilla/content/shared/src/nsStyleStruct.cpp
@@ -128,7 +128,33 @@ inline nscoord CalcSideFor(const nsIFrame* aFrame, const nsStyleCoord& aCoord,
if (isBase) {
nsSize size;
frame->GetSize(size);
- baseWidth = size.width; // not really width, need to subtract out padding...
+ baseWidth = size.width;
+ // subtract border of containing block
+ const nsStyleBorder* borderData = nsnull;
+ frame->GetStyleData(eStyleStruct_Border,
+ (const nsStyleStruct*&)borderData);
+ if (borderData) {
+ nsMargin border;
+ borderData->CalcBorderFor(frame, border);
+ baseWidth -= (border.left + border.right);
+ }
+ // if aFrame is not absolutely positioned, subtract
+ // padding of containing block
+ const nsStyleDisplay* displayData = nsnull;
+ aFrame->GetStyleData(eStyleStruct_Display,
+ (const nsStyleStruct*&)displayData);
+ if (displayData &&
+ displayData->mPosition != NS_STYLE_POSITION_ABSOLUTE &&
+ displayData->mPosition != NS_STYLE_POSITION_FIXED) {
+ const nsStylePadding* paddingData = nsnull;
+ frame->GetStyleData(eStyleStruct_Padding,
+ (const nsStyleStruct*&)paddingData);
+ if (paddingData) {
+ nsMargin padding;
+ paddingData->CalcPaddingFor(frame, padding);
+ baseWidth -= (padding.left + padding.right);
+ }
+ }
break;
}
frame->GetParent(&frame);
diff --git a/mozilla/layout/style/nsComputedDOMStyle.cpp b/mozilla/layout/style/nsComputedDOMStyle.cpp
index aad4a013518..20879fdefe8 100644
--- a/mozilla/layout/style/nsComputedDOMStyle.cpp
+++ b/mozilla/layout/style/nsComputedDOMStyle.cpp
@@ -41,6 +41,8 @@
#include "nsIPresContext.h"
#include "nsIContent.h"
#include "nsIFrame.h"
+#include "nsIScrollableFrame.h"
+#include "nsLayoutAtoms.h"
#include "nsIDOMElement.h"
#include "nsIStyleContext.h"
#include "nsROCSSPrimitiveValue.h"
@@ -82,20 +84,31 @@ public:
private:
//Helpers
- nsresult GetAbsoluteFrameRect(nsIFrame *aFrame, nsRect& aRect);
+ nsresult GetOffsetWidthFor(PRUint8 aSide, nsIFrame *aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue);
+ nsresult GetAbsoluteOffset(PRUint8 aSide, nsIFrame *aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue);
+ nsresult GetRelativeOffset(PRUint8 aSide, nsIFrame *aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue);
+ nsresult GetStaticOffset(PRUint8 aSide, nsIFrame *aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue);
+ nsIFrame* GetContainingBlock(nsIFrame *aFrame);
nsresult GetStyleData(nsStyleStructID aID,
const nsStyleStruct*& aStyleStruct,
nsIFrame* aFrame=0);
nsresult GetPaddingWidthFor(PRUint8 aSide, nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue);
+ nscoord GetPaddingWidthCoordFor(PRUint8 aSide, nsIFrame *aFrame);
nsresult GetBorderStyleFor(PRUint8 aSide, nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue);
nsresult GetBorderWidthFor(PRUint8 aSide, nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue);
+ nscoord GetBorderWidthCoordFor(PRUint8 aSide, nsIFrame *aFrame);
nsresult GetBorderColorFor(PRUint8 aSide, nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue);
nsresult GetMarginWidthFor(PRUint8 aSide, nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue);
+ nscoord GetMarginWidthCoordFor(PRUint8 aSide, nsIFrame *aFrame);
// Properties
nsresult GetWidth(nsIFrame *aFrame, nsIDOMCSSPrimitiveValue*& aValue);
@@ -205,7 +218,7 @@ private:
nsCOMPtr mContent;
// When a frame is unavailable strong reference to the
// style context while we're accessing the data from in.
- nsCOMPtr mStyleContextHolder;
+ nsCOMPtr mStyleContextHolder;
nsCOMPtr mPseudo;
float mT2P; // For unit conversions
@@ -830,16 +843,7 @@ nsresult
nsComputedDOMStyle::GetBottom(nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue)
{
- nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
- NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
-
- nsRect rect;
- GetAbsoluteFrameRect(aFrame, rect);
-
- val->SetTwips(rect.y + rect.height);
-
- return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
- (void **)&aValue);
+ return GetOffsetWidthFor(NS_SIDE_BOTTOM, aFrame, aValue);
}
@@ -1371,18 +1375,21 @@ nsComputedDOMStyle::GetZIndex(nsIFrame *aFrame,
const nsStylePosition* position = nsnull;
nsAutoString zindex;
- do {
- GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position,
- aFrame);
-
- if(position){
- if(position->mZIndex.GetUnit()==eStyleUnit_Integer) {
- zindex.AppendInt(position->mZIndex.GetIntValue(), 10);
- break;
- }
+ GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position, aFrame);
+ while (position) {
+ if (position->mZIndex.GetUnit() == eStyleUnit_Integer) {
+ zindex.AppendInt(position->mZIndex.GetIntValue(), 10);
+ break;
+ }
+ if (aFrame) {
aFrame->GetParent(&aFrame);
}
- }while(aFrame && position);
+ if (aFrame) {
+ aFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position);
+ } else {
+ position = nsnull;
+ }
+ }
val->SetString(zindex);
@@ -1696,11 +1703,48 @@ nsComputedDOMStyle::GetHeight(nsIFrame *aFrame,
nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
- nsRect rect;
- GetAbsoluteFrameRect(aFrame, rect);
-
- val->SetTwips(rect.height);
+ if (aFrame) {
+ // Flush all pending notifications so that our frames are up to date
+ nsCOMPtr document;
+ mContent->GetDocument(*getter_AddRefs(document));
+ if (document) {
+ document->FlushPendingNotifications();
+ }
+
+ const nsStyleDisplay* displayData = nsnull;
+ GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)displayData, aFrame);
+ if (displayData && displayData->mDisplay == NS_STYLE_DISPLAY_INLINE) {
+ nsFrameState frameState;
+ aFrame->GetFrameState(&frameState);
+ if (! (frameState & NS_FRAME_REPLACED_ELEMENT)) {
+ // XXX no useful height we can give for non-replaced inlines yet
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+ }
+
+ nsRect rect;
+ nsMargin padding;
+ nsMargin border;
+ aFrame->GetRect(rect);
+ const nsStylePadding* paddingData=nsnull;
+ GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)paddingData, aFrame);
+ if (paddingData) {
+ paddingData->CalcPaddingFor(aFrame, padding);
+ }
+ const nsStyleBorder* borderData=nsnull;
+ GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData, aFrame);
+ if (borderData) {
+ borderData->CalcBorderFor(aFrame, border);
+ }
+
+ val->SetTwips(rect.height - padding.top - padding.bottom -
+ border.top - border.bottom);
+ } else {
+ // XXX no frame. This property makes no sense in this case
+ val->SetTwips(0);
+ }
+
return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
(void **)&aValue);
}
@@ -1709,16 +1753,7 @@ nsresult
nsComputedDOMStyle::GetLeft(nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue)
{
- nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
- NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
-
- nsRect rect;
- GetAbsoluteFrameRect(aFrame, rect);
-
- val->SetTwips(rect.x);
-
- return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
- (void **)&aValue);
+ return GetOffsetWidthFor(NS_SIDE_LEFT, aFrame, aValue);
}
#if 0
@@ -1977,16 +2012,7 @@ nsresult
nsComputedDOMStyle::GetRight(nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue)
{
- nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
- NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
-
- nsRect rect;
- GetAbsoluteFrameRect(aFrame, rect);
-
- val->SetTwips(rect.x + rect.width);
-
- return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
- (void **)&aValue);
+ return GetOffsetWidthFor(NS_SIDE_RIGHT, aFrame, aValue);
}
#if 0
@@ -2073,16 +2099,7 @@ nsresult
nsComputedDOMStyle::GetTop(nsIFrame *aFrame,
nsIDOMCSSPrimitiveValue*& aValue)
{
- nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
- NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
-
- nsRect rect;
- GetAbsoluteFrameRect(aFrame, rect);
-
- val->SetTwips(rect.y);
-
- return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
- (void **)&aValue);
+ return GetOffsetWidthFor(NS_SIDE_TOP, aFrame, aValue);
}
#if 0
@@ -2142,85 +2159,297 @@ nsComputedDOMStyle::GetROCSSPrimitiveValue()
}
nsresult
-nsComputedDOMStyle::GetAbsoluteFrameRect(nsIFrame *aFrame, nsRect& aRect)
+nsComputedDOMStyle::GetOffsetWidthFor(PRUint8 aSide, nsIFrame* aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue)
{
- nsresult res = NS_OK;
+ const nsStyleDisplay* display = nsnull;
+ GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display, aFrame);
- aRect.x = aRect.y = 0;
- aRect.Empty();
-
- if (!aFrame) {
- return NS_OK;
- }
-
- // Flush all pending notifications so that our frames are uptodate
+ // Flush all pending notifications so that our frames are up to date
nsCOMPtr document;
mContent->GetDocument(*getter_AddRefs(document));
-
if (document) {
document->FlushPendingNotifications();
}
- // Get the union of all rectangles in this and continuation frames
- nsIFrame* next = aFrame;
- do {
- nsRect rect;
- next->GetRect(rect);
- aRect.UnionRect(aRect, rect);
- next->GetNextInFlow(&next);
- } while (nsnull != next);
-
- nsIFrame* frame = aFrame;
- nsPoint origin(0, 0), tmp(0, 0);
- nsFrameState position;
- do {
- frame->GetOrigin(tmp);
- origin += tmp;
-
- frame->GetFrameState(&position);
- if(position & NS_FRAME_OUT_OF_FLOW) {
- break; // Do not include parent if absolutely positioned - Bug 49942
- }
- // Add the parent's origin to our own to
- // get to the right coordinate system
- frame->GetParent(&frame);
- } while(frame);
-
- // For the origin, add in the border for the frame
- const nsStyleBorder* border;
- const nsStylePadding* padding;
- nsStyleCoord coord;
- GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)border, aFrame);
- GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)padding, aFrame);
- if (border && padding) {
- if (eStyleUnit_Coord == border->mBorder.GetLeftUnit()) {
- origin.x += border->mBorder.GetLeft(coord).GetCoordValue();
- aRect.width -= border->mBorder.GetLeft(coord).GetCoordValue();
- //aRect.width -= margin->mMargin.GetLeft(coord).GetCoordValue();
- aRect.width -= padding->mPadding.GetLeft(coord).GetCoordValue();
- }
- if (eStyleUnit_Coord == border->mBorder.GetTopUnit()) {
- origin.y += border->mBorder.GetTop(coord).GetCoordValue();
- aRect.height -= border->mBorder.GetTop(coord).GetCoordValue();
- //aRect.height -= margin->mMargin.GetTop(coord).GetCoordValue();
- aRect.height -= padding->mPadding.GetTop(coord).GetCoordValue();
- }
- if (eStyleUnit_Coord == border->mBorder.GetRightUnit()) {
- aRect.width -= border->mBorder.GetRight(coord).GetCoordValue();
- //aRect.width -= margin->mMargin.GetRight(coord).GetCoordValue();
- aRect.width -= padding->mPadding.GetRight(coord).GetCoordValue();
- }
- if (eStyleUnit_Coord == border->mBorder.GetBottomUnit()) {
- aRect.height -= border->mBorder.GetBottom(coord).GetCoordValue();
- //aRect.height -= margin->mMargin.GetBottom(coord).GetCoordValue();
- aRect.height -= padding->mPadding.GetBottom(coord).GetCoordValue();
+ nsresult rv = NS_OK;
+ if (display) {
+ switch (display->mPosition) {
+ case NS_STYLE_POSITION_NORMAL:
+ rv = GetStaticOffset(aSide, aFrame, aValue);
+ break;
+ case NS_STYLE_POSITION_RELATIVE:
+ rv = GetRelativeOffset(aSide, aFrame, aValue);
+ break;
+ case NS_STYLE_POSITION_ABSOLUTE:
+ case NS_STYLE_POSITION_FIXED:
+ rv = GetAbsoluteOffset(aSide, aFrame, aValue);
+ break;
+ default:
+ NS_WARNING("double check the position");
+ break;
}
}
- aRect.x = origin.x;
- aRect.y = origin.y;
+ return rv;
+}
- return res;
+nsresult
+nsComputedDOMStyle::GetAbsoluteOffset(PRUint8 aSide, nsIFrame* aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue)
+{
+ nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
+ NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
+
+ nsIFrame* container = GetContainingBlock(aFrame);
+ if (container) {
+ nsRect rect;
+ nsRect containerRect;
+ nscoord margin = GetMarginWidthCoordFor(aSide, aFrame);
+ nscoord border = GetBorderWidthCoordFor(aSide, container);
+ nscoord horScrollBarHeight = 0;
+ nscoord verScrollBarWidth = 0;
+ aFrame->GetRect(rect);
+ container->GetRect(containerRect);
+
+ nsCOMPtr typeAtom;
+ container->GetFrameType(getter_AddRefs(typeAtom));
+ if (typeAtom == nsLayoutAtoms::viewportFrame) {
+ // For absolutely positioned frames scrollbars are taken into
+ // account by virtue of getting a containing block that does
+ // _not_ include the scrollbars. For fixed positioned frames,
+ // the containing block is the viewport, which _does_ include
+ // scrollbars. We have to do some extra work.
+ nsIFrame* scrollingChild;
+ nsCOMPtr presShell = do_QueryReferent(mPresShellWeak);
+ NS_ASSERTION(presShell, "Must have a presshell!");
+ nsCOMPtr presContext;
+ presShell->GetPresContext(getter_AddRefs(presContext));
+ // the first child in the default frame list is what we want
+ container->FirstChild(presContext, nsnull, &scrollingChild);
+ nsCOMPtr scrollFrame(do_QueryInterface(scrollingChild));
+ if (scrollFrame) {
+ scrollFrame->GetScrollbarSizes(presContext, &verScrollBarWidth,
+ &horScrollBarHeight);
+ PRBool verScrollBarVisible;
+ PRBool horScrollBarVisible;
+ scrollFrame->GetScrollbarVisibility(presContext, &verScrollBarVisible,
+ &horScrollBarVisible);
+ if (!verScrollBarVisible) {
+ verScrollBarWidth = 0;
+ }
+ if (!horScrollBarVisible) {
+ horScrollBarHeight = 0;
+ }
+ }
+ }
+ nscoord offset = 0;
+ switch (aSide) {
+ case NS_SIDE_TOP:
+ offset = rect.y - margin - border;
+ break;
+ case NS_SIDE_RIGHT:
+ offset = containerRect.width - rect.width -
+ rect.x - margin - border - verScrollBarWidth;
+ break;
+ case NS_SIDE_BOTTOM:
+ offset = containerRect.height - rect.height -
+ rect.y - margin - border - horScrollBarHeight;
+ break;
+ case NS_SIDE_LEFT:
+ offset = rect.x - margin - border;
+ break;
+ default:
+ NS_WARNING("double check the side");
+ break;
+ }
+ val->SetTwips(offset);
+ } else {
+ // XXX no frame. This property makes no sense
+ val->SetTwips(0);
+ }
+
+ return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
+ (void **)&aValue);
+}
+
+nsresult
+nsComputedDOMStyle::GetRelativeOffset(PRUint8 aSide, nsIFrame* aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue)
+{
+ nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
+ NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
+
+ const nsStylePosition* positionData = nsnull;
+ GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)positionData, aFrame);
+ if (positionData) {
+ nsStyleCoord coord;
+ PRInt32 sign = 1;
+ switch (aSide) {
+ case NS_SIDE_TOP:
+ positionData->mOffset.GetTop(coord);
+ if (coord.GetUnit() != eStyleUnit_Coord &&
+ coord.GetUnit() != eStyleUnit_Percent) {
+ positionData->mOffset.GetBottom(coord);
+ sign = -1;
+ }
+ break;
+ case NS_SIDE_RIGHT:
+ positionData->mOffset.GetRight(coord);
+ if (coord.GetUnit() != eStyleUnit_Coord &&
+ coord.GetUnit() != eStyleUnit_Percent) {
+ positionData->mOffset.GetLeft(coord);
+ sign = -1;
+ }
+ break;
+ case NS_SIDE_BOTTOM:
+ positionData->mOffset.GetBottom(coord);
+ if (coord.GetUnit() != eStyleUnit_Coord &&
+ coord.GetUnit() != eStyleUnit_Percent) {
+ positionData->mOffset.GetTop(coord);
+ sign = -1;
+ }
+ break;
+ case NS_SIDE_LEFT:
+ positionData->mOffset.GetLeft(coord);
+ if (coord.GetUnit() != eStyleUnit_Coord &&
+ coord.GetUnit() != eStyleUnit_Percent) {
+ positionData->mOffset.GetRight(coord);
+ sign = -1;
+ }
+ break;
+ default:
+ NS_WARNING("double check the side");
+ break;
+ }
+
+ nsIFrame* container = nsnull;
+ const nsStyleBorder* borderData = nsnull;
+ const nsStylePadding* paddingData = nsnull;
+ nsMargin border;
+ nsMargin padding;
+ nsRect rect;
+ switch(coord.GetUnit()) {
+ case eStyleUnit_Coord:
+ val->SetTwips(sign * coord.GetCoordValue());
+ break;
+ case eStyleUnit_Percent:
+ container = GetContainingBlock(aFrame);
+ if (container) {
+ container->GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData);
+ if (borderData) {
+ borderData->CalcBorderFor(container, border);
+ }
+ container->GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)paddingData);
+ if (paddingData) {
+ paddingData->CalcPaddingFor(container, padding);
+ }
+ container->GetRect(rect);
+ if (aSide == NS_SIDE_LEFT || aSide == NS_SIDE_RIGHT) {
+ val->SetTwips(sign * coord.GetPercentValue() *
+ (rect.width - border.left - border.right -
+ padding.left - padding.right));
+ } else {
+ val->SetTwips(sign * coord.GetPercentValue() *
+ (rect.height - border.top - border.bottom -
+ padding.top - padding.bottom));
+ }
+ } else {
+ // XXX no containing block.
+ val->SetTwips(0);
+ }
+ break;
+ default:
+ NS_WARNING("double check the unit");
+ val->SetTwips(0);
+ break;
+ }
+ }
+
+ return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
+ (void **)&aValue);
+}
+
+nsresult
+nsComputedDOMStyle::GetStaticOffset(PRUint8 aSide, nsIFrame* aFrame,
+ nsIDOMCSSPrimitiveValue*& aValue)
+
+{
+ /*
+ This does not work correctly yet. Specifically, we _always_
+ return computed values here. This needs to be worked on.
+ */
+ return NS_ERROR_NOT_IMPLEMENTED;
+#if 0
+ nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
+ NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
+
+ const nsStylePosition* positionData = nsnull;
+ GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)positionData, aFrame);
+ if (positionData) {
+ nsStyleCoord coord;
+ switch (aSide) {
+ case NS_SIDE_TOP:
+ positionData->mOffset.GetTop(coord);
+ break;
+ case NS_SIDE_RIGHT:
+ positionData->mOffset.GetRight(coord);
+ break;
+ case NS_SIDE_BOTTOM:
+ positionData->mOffset.GetBottom(coord);
+ break;
+ case NS_SIDE_LEFT:
+ positionData->mOffset.GetLeft(coord);
+ break;
+ default:
+ NS_WARNING("double check the side");
+ break;
+ }
+
+ char buf[16];
+ PRInt32 len;
+ switch(coord.GetUnit()) {
+ case eStyleUnit_Coord:
+ val->SetTwips(coord.GetCoordValue());
+ break;
+ case eStyleUnit_Percent:
+ len = PR_snprintf(buf, sizeof(buf), "%d%%",
+ int(coord.GetPercentValue() * 100.0));
+ val->SetString(buf);
+ break;
+ default:
+ NS_WARNING("double check the unit");
+ val->SetTwips(0);
+ break;
+ }
+ }
+
+ return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
+ (void **)&aValue);
+#endif
+}
+
+
+nsIFrame*
+nsComputedDOMStyle::GetContainingBlock(nsIFrame *aFrame)
+{
+ if (!aFrame) {
+ // Tell caller that they have no containing block, seeing as they
+ // are not being displayed
+ return nsnull;
+ }
+ nsIFrame* container = aFrame;
+ PRBool done = PR_FALSE;
+ do {
+ container->GetParent(&container);
+ if (container) {
+ (container)->IsPercentageBase(done);
+ }
+ } while (!done && container);
+
+ NS_POSTCONDITION(container, "Frame has no containing block");
+
+ return container;
}
nsresult
@@ -2231,7 +2460,9 @@ nsComputedDOMStyle::GetStyleData(nsStyleStructID aID,
if(aFrame && !mPseudo) {
aFrame->GetStyleData(aID, aStyleStruct);
}
- else {
+ else if (mStyleContextHolder) {
+ aStyleStruct = mStyleContextHolder->GetStyleData(aID);
+ } else {
nsCOMPtr presShell=do_QueryReferent(mPresShellWeak);
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
@@ -2254,6 +2485,7 @@ nsComputedDOMStyle::GetStyleData(nsStyleStructID aID,
mStyleContextHolder=sctx;
}
}
+ NS_ASSERTION(aStyleStruct, "Failed to get a style struct");
return NS_OK;
}
@@ -2264,50 +2496,79 @@ nsComputedDOMStyle::GetPaddingWidthFor(PRUint8 aSide,
{
nsROCSSPrimitiveValue* val=GetROCSSPrimitiveValue();
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
-
- const nsStylePadding* padding=nsnull;
- GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)padding, aFrame);
-
- if(padding) {
- nsStyleCoord coord;
- switch(aSide) {
- case NS_SIDE_TOP:
- padding->mPadding.GetTop(coord); break;
- case NS_SIDE_BOTTOM :
- padding->mPadding.GetBottom(coord); break;
- case NS_SIDE_LEFT :
- padding->mPadding.GetLeft(coord); break;
- case NS_SIDE_RIGHT :
- padding->mPadding.GetRight(coord); break;
- default:
- NS_WARNING("double check the side");
- break;
- }
-
- switch(coord.GetUnit()) {
- case eStyleUnit_Coord:
- val->SetTwips(coord.GetCoordValue()); break;
- case eStyleUnit_Percent:
- {
- nsIFrame* parent=nsnull;
- aFrame->GetParent(&parent);
- if(parent) {
- nsRect rect;
- parent->GetRect(rect);
- val->SetTwips(nscoord(coord.GetPercentValue() * rect.width));
- break; // intentionally breaking here...
- }
- }
- default:
- NS_WARNING("double check the unit");
- break;
- }
- }
+
+ nscoord width = GetPaddingWidthCoordFor(aSide, aFrame);
+ val->SetTwips(width);
return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
(void **)&aValue);
}
+nscoord
+nsComputedDOMStyle::GetPaddingWidthCoordFor(PRUint8 aSide, nsIFrame* aFrame)
+{
+ const nsStylePadding* paddingData=nsnull;
+ GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)paddingData, aFrame);
+
+ if(paddingData) {
+ nsMargin padding;
+ paddingData->CalcPaddingFor(aFrame, padding);
+ switch(aSide) {
+ case NS_SIDE_TOP :
+ return padding.top;
+ break;
+ case NS_SIDE_BOTTOM :
+ return padding.bottom;
+ break;
+ case NS_SIDE_LEFT :
+ return padding.left;
+ break;
+ case NS_SIDE_RIGHT :
+ return padding.right;
+ break;
+ default:
+ NS_WARNING("double check the side");
+ break;
+ }
+ }
+
+ return 0;
+}
+
+nscoord
+nsComputedDOMStyle::GetBorderWidthCoordFor(PRUint8 aSide, nsIFrame *aFrame)
+{
+ nsROCSSPrimitiveValue* val=GetROCSSPrimitiveValue();
+ NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
+
+ const nsStyleBorder* borderData = nsnull;
+ GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData, aFrame);
+
+ if(borderData) {
+ nsMargin border;
+ borderData->CalcBorderFor(aFrame, border);
+ switch(aSide) {
+ case NS_SIDE_TOP :
+ return border.top;
+ break;
+ case NS_SIDE_BOTTOM :
+ return border.bottom;
+ break;
+ case NS_SIDE_LEFT :
+ return border.left;
+ break;
+ case NS_SIDE_RIGHT :
+ return border.right;
+ break;
+ default:
+ NS_WARNING("double check the side");
+ break;
+ }
+ }
+
+ return 0;
+}
+
nsresult
nsComputedDOMStyle::GetBorderWidthFor(PRUint8 aSide,
nsIFrame *aFrame,
@@ -2407,47 +2668,42 @@ nsComputedDOMStyle::GetMarginWidthFor(PRUint8 aSide,
nsROCSSPrimitiveValue* val=GetROCSSPrimitiveValue();
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
- const nsStyleMargin* margin=nsnull;
- GetStyleData(eStyleStruct_Margin, (const nsStyleStruct*&)margin, aFrame);
+ nscoord width = GetMarginWidthCoordFor(aSide, aFrame);
+ val->SetTwips(width);
- if(margin) {
- nsStyleCoord coord;
+ return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
+ (void **)&aValue);
+}
+
+nscoord
+nsComputedDOMStyle::GetMarginWidthCoordFor(PRUint8 aSide,
+ nsIFrame *aFrame)
+{
+ const nsStyleMargin* marginData=nsnull;
+ GetStyleData(eStyleStruct_Margin, (const nsStyleStruct*&)marginData, aFrame);
+ if(marginData) {
+ nsMargin margin;
+ marginData->CalcMarginFor(aFrame, margin);
switch(aSide) {
case NS_SIDE_TOP :
- margin->mMargin.GetTop(coord); break;
+ return margin.top;
+ break;
case NS_SIDE_BOTTOM :
- margin->mMargin.GetBottom(coord); break;
+ return margin.bottom;
+ break;
case NS_SIDE_LEFT :
- margin->mMargin.GetLeft(coord); break;
+ return margin.left;
+ break;
case NS_SIDE_RIGHT :
- margin->mMargin.GetRight(coord); break;
+ return margin.right;
+ break;
default:
NS_WARNING("double check the side");
break;
}
-
- switch(coord.GetUnit()) {
- case eStyleUnit_Coord:
- val->SetTwips(coord.GetCoordValue()); break;
- case eStyleUnit_Percent:
- {
- nsIFrame* parent=nsnull;
- aFrame->GetParent(&parent);
- if(parent) {
- nsRect rect;
- parent->GetRect(rect);
- val->SetTwips(nscoord(coord.GetPercentValue() * rect.width));
- break; // intentionally breaking here...
- }
- }
- default:
- NS_WARNING("double check the unit");
- break;
- }
}
- return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
- (void **)&aValue);
+ return 0;
}
nsresult
@@ -2482,10 +2738,46 @@ nsComputedDOMStyle::GetWidth(nsIFrame *aFrame,
nsROCSSPrimitiveValue* val=GetROCSSPrimitiveValue();
NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
- nsRect rect;
- GetAbsoluteFrameRect(aFrame, rect);
-
- val->SetTwips(rect.width);
+ if (aFrame) {
+ // Flush all pending notifications so that our frames are up to date
+ nsCOMPtr document;
+ mContent->GetDocument(*getter_AddRefs(document));
+
+ if (document) {
+ document->FlushPendingNotifications();
+ }
+
+ const nsStyleDisplay* displayData = nsnull;
+ GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)displayData, aFrame);
+ if (displayData && displayData->mDisplay == NS_STYLE_DISPLAY_INLINE) {
+ nsFrameState frameState;
+ aFrame->GetFrameState(&frameState);
+ if (! (frameState & NS_FRAME_REPLACED_ELEMENT)) {
+ // XXX no useful width we can give for non-replaced inlines yet
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+ }
+
+ nsRect rect;
+ nsMargin padding;
+ nsMargin border;
+ aFrame->GetRect(rect);
+ const nsStylePadding* paddingData=nsnull;
+ GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)paddingData, aFrame);
+ if (paddingData) {
+ paddingData->CalcPaddingFor(aFrame, padding);
+ }
+ const nsStyleBorder* borderData=nsnull;
+ GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData, aFrame);
+ if (borderData) {
+ borderData->CalcBorderFor(aFrame, border);
+ }
+ val->SetTwips(rect.width - padding.left - padding.right -
+ border.left - border.right);
+ } else {
+ // XXX no frame. This property makes no sense in this case
+ val->SetTwips(0);
+ }
return val->QueryInterface(NS_GET_IID(nsIDOMCSSPrimitiveValue),
(void **)&aValue);
diff --git a/mozilla/layout/style/nsStyleStruct.cpp b/mozilla/layout/style/nsStyleStruct.cpp
index 81f15c90aed..9263ad5fd46 100644
--- a/mozilla/layout/style/nsStyleStruct.cpp
+++ b/mozilla/layout/style/nsStyleStruct.cpp
@@ -128,7 +128,33 @@ inline nscoord CalcSideFor(const nsIFrame* aFrame, const nsStyleCoord& aCoord,
if (isBase) {
nsSize size;
frame->GetSize(size);
- baseWidth = size.width; // not really width, need to subtract out padding...
+ baseWidth = size.width;
+ // subtract border of containing block
+ const nsStyleBorder* borderData = nsnull;
+ frame->GetStyleData(eStyleStruct_Border,
+ (const nsStyleStruct*&)borderData);
+ if (borderData) {
+ nsMargin border;
+ borderData->CalcBorderFor(frame, border);
+ baseWidth -= (border.left + border.right);
+ }
+ // if aFrame is not absolutely positioned, subtract
+ // padding of containing block
+ const nsStyleDisplay* displayData = nsnull;
+ aFrame->GetStyleData(eStyleStruct_Display,
+ (const nsStyleStruct*&)displayData);
+ if (displayData &&
+ displayData->mPosition != NS_STYLE_POSITION_ABSOLUTE &&
+ displayData->mPosition != NS_STYLE_POSITION_FIXED) {
+ const nsStylePadding* paddingData = nsnull;
+ frame->GetStyleData(eStyleStruct_Padding,
+ (const nsStyleStruct*&)paddingData);
+ if (paddingData) {
+ nsMargin padding;
+ paddingData->CalcPaddingFor(frame, padding);
+ baseWidth -= (padding.left + padding.right);
+ }
+ }
break;
}
frame->GetParent(&frame);