зеркало из https://github.com/mozilla/gecko-dev.git
Fix getComputedStyle() position/size calculations. Bug 84599 and bug
94855, r=glazou, sr=attinasi
This commit is contained in:
Родитель
c8e5ffae33
Коммит
c255aa1143
|
@ -47,6 +47,7 @@ REQUIRES = xpcom \
|
|||
xuldoc \
|
||||
xpconnect \
|
||||
pref \
|
||||
view \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
|
|
|
@ -41,6 +41,7 @@ REQUIRES = xpcom \
|
|||
layout \
|
||||
gfx \
|
||||
content_xul \
|
||||
view \
|
||||
$(NULL)
|
||||
|
||||
DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
|
||||
|
|
|
@ -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<nsIContent> mContent;
|
||||
// When a frame is unavailable strong reference to the
|
||||
// style context while we're accessing the data from in.
|
||||
nsCOMPtr<nsISupports> mStyleContextHolder;
|
||||
nsCOMPtr<nsIStyleContext> mStyleContextHolder;
|
||||
nsCOMPtr<nsIAtom> 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<nsIDocument> 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<nsIDocument> 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<nsIAtom> 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<nsIPresShell> presShell = do_QueryReferent(mPresShellWeak);
|
||||
NS_ASSERTION(presShell, "Must have a presshell!");
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
presShell->GetPresContext(getter_AddRefs(presContext));
|
||||
// the first child in the default frame list is what we want
|
||||
container->FirstChild(presContext, nsnull, &scrollingChild);
|
||||
nsCOMPtr<nsIScrollableFrame> 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<nsIPresShell> 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<nsIDocument> 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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<nsIContent> mContent;
|
||||
// When a frame is unavailable strong reference to the
|
||||
// style context while we're accessing the data from in.
|
||||
nsCOMPtr<nsISupports> mStyleContextHolder;
|
||||
nsCOMPtr<nsIStyleContext> mStyleContextHolder;
|
||||
nsCOMPtr<nsIAtom> 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<nsIDocument> 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<nsIDocument> 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<nsIAtom> 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<nsIPresShell> presShell = do_QueryReferent(mPresShellWeak);
|
||||
NS_ASSERTION(presShell, "Must have a presshell!");
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
presShell->GetPresContext(getter_AddRefs(presContext));
|
||||
// the first child in the default frame list is what we want
|
||||
container->FirstChild(presContext, nsnull, &scrollingChild);
|
||||
nsCOMPtr<nsIScrollableFrame> 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<nsIPresShell> 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<nsIDocument> 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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче