зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 2e8dfe209f09 due to unit test bustage
This commit is contained in:
Родитель
944e99b67e
Коммит
1fef5b8148
|
@ -125,12 +125,6 @@
|
|||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsIFocusController.h"
|
||||
#include "nsIControllers.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsIScrollableViewProvider.h"
|
||||
#include "nsXBLInsertionPoint.h"
|
||||
#include "nsICSSStyleRule.h" /* For nsCSSSelectorList */
|
||||
#include "nsCSSRuleProcessor.h"
|
||||
|
@ -804,315 +798,6 @@ nsNSElementTearoff::GetElementsByClassName(const nsAString& aClasses,
|
|||
return nsDocument::GetElementsByClassNameHelper(mContent, aClasses, aReturn);
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsGenericElement::GetStyledFrame()
|
||||
{
|
||||
nsIFrame *frame = GetPrimaryFrame(Flush_Layout);
|
||||
|
||||
return (frame && frame->GetType() == nsGkAtoms::tableOuterFrame) ?
|
||||
frame->GetFirstChild(nsnull) : frame;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericElement::GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent)
|
||||
{
|
||||
*aOffsetParent = nsnull;
|
||||
aRect = nsRect();
|
||||
|
||||
nsIFrame* frame = GetStyledFrame();
|
||||
if (!frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsPoint origin = frame->GetPosition();
|
||||
aRect.x = nsPresContext::AppUnitsToIntCSSPixels(origin.x);
|
||||
aRect.y = nsPresContext::AppUnitsToIntCSSPixels(origin.y);
|
||||
|
||||
// Get the union of all rectangles in this and continuation frames.
|
||||
// It doesn't really matter what we use as aRelativeTo here, since
|
||||
// we only care about the size. Using 'parent' might make things
|
||||
// a bit faster by speeding up the internal GetOffsetTo operations.
|
||||
nsRect rcFrame = nsLayoutUtils::GetAllInFlowRectsUnion(frame, nsnull);
|
||||
aRect.width = nsPresContext::AppUnitsToIntCSSPixels(rcFrame.width);
|
||||
aRect.height = nsPresContext::AppUnitsToIntCSSPixels(rcFrame.height);
|
||||
}
|
||||
|
||||
void
|
||||
nsNSElementTearoff::GetScrollInfo(nsIScrollableView **aScrollableView,
|
||||
nsIFrame **aFrame)
|
||||
{
|
||||
*aScrollableView = nsnull;
|
||||
|
||||
// it isn't clear what to return for SVG nodes, so just return nothing
|
||||
if (mContent->IsNodeOfType(nsINode::eSVG)) {
|
||||
if (aFrame)
|
||||
*aFrame = nsnull;
|
||||
return;
|
||||
}
|
||||
|
||||
nsIFrame* frame =
|
||||
(static_cast<nsGenericElement*>(mContent))->GetStyledFrame();
|
||||
|
||||
if (aFrame) {
|
||||
*aFrame = frame;
|
||||
}
|
||||
if (!frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the scrollable frame
|
||||
nsIScrollableFrame *scrollFrame = nsnull;
|
||||
CallQueryInterface(frame, &scrollFrame);
|
||||
|
||||
if (!scrollFrame) {
|
||||
nsIScrollableViewProvider *scrollProvider = nsnull;
|
||||
CallQueryInterface(frame, &scrollProvider);
|
||||
// menu frames implement nsIScrollableViewProvider but we don't want
|
||||
// to use it here.
|
||||
if (scrollProvider && frame->GetType() != nsGkAtoms::menuFrame) {
|
||||
*aScrollableView = scrollProvider->GetScrollableView();
|
||||
if (*aScrollableView) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nsIDocument* doc = mContent->GetCurrentDoc();
|
||||
PRBool quirksMode = doc &&
|
||||
doc->GetCompatibilityMode() == eCompatibility_NavQuirks;
|
||||
if ((quirksMode && mContent->NodeInfo()->Equals(nsGkAtoms::body)) ||
|
||||
(!quirksMode && mContent->NodeInfo()->Equals(nsGkAtoms::html))) {
|
||||
// In quirks mode, the scroll info for the body element should map to the
|
||||
// scroll info for the nearest scrollable frame above the body element
|
||||
// (i.e. the root scrollable frame). This is what IE6 does in quirks
|
||||
// mode. In strict mode the root scrollable frame corresponds to the
|
||||
// html element in IE6, so we map the scroll info for the html element to
|
||||
// the root scrollable frame.
|
||||
|
||||
do {
|
||||
frame = frame->GetParent();
|
||||
|
||||
if (!frame) {
|
||||
break;
|
||||
}
|
||||
|
||||
CallQueryInterface(frame, &scrollFrame);
|
||||
} while (!scrollFrame);
|
||||
}
|
||||
|
||||
if (!scrollFrame) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the scrollable view
|
||||
*aScrollableView = scrollFrame->GetScrollableView();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSElementTearoff::GetScrollTop(PRInt32* aScrollTop)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aScrollTop);
|
||||
*aScrollTop = 0;
|
||||
|
||||
nsIScrollableView *view;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
GetScrollInfo(&view);
|
||||
|
||||
if (view) {
|
||||
nscoord xPos, yPos;
|
||||
rv = view->GetScrollPosition(xPos, yPos);
|
||||
|
||||
*aScrollTop = nsPresContext::AppUnitsToIntCSSPixels(yPos);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSElementTearoff::SetScrollTop(PRInt32 aScrollTop)
|
||||
{
|
||||
nsIScrollableView *view;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
GetScrollInfo(&view);
|
||||
|
||||
if (view) {
|
||||
nscoord xPos, yPos;
|
||||
|
||||
rv = view->GetScrollPosition(xPos, yPos);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = view->ScrollTo(xPos, nsPresContext::CSSPixelsToAppUnits(aScrollTop),
|
||||
NS_VMREFRESH_IMMEDIATE);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSElementTearoff::GetScrollLeft(PRInt32* aScrollLeft)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aScrollLeft);
|
||||
*aScrollLeft = 0;
|
||||
|
||||
nsIScrollableView *view;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
GetScrollInfo(&view);
|
||||
|
||||
if (view) {
|
||||
nscoord xPos, yPos;
|
||||
rv = view->GetScrollPosition(xPos, yPos);
|
||||
|
||||
*aScrollLeft = nsPresContext::AppUnitsToIntCSSPixels(xPos);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSElementTearoff::SetScrollLeft(PRInt32 aScrollLeft)
|
||||
{
|
||||
nsIScrollableView *view;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
GetScrollInfo(&view);
|
||||
|
||||
if (view) {
|
||||
nscoord xPos, yPos;
|
||||
rv = view->GetScrollPosition(xPos, yPos);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = view->ScrollTo(nsPresContext::CSSPixelsToAppUnits(aScrollLeft),
|
||||
yPos, NS_VMREFRESH_IMMEDIATE);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSElementTearoff::GetScrollHeight(PRInt32* aScrollHeight)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aScrollHeight);
|
||||
*aScrollHeight = 0;
|
||||
|
||||
if (mContent->IsNodeOfType(nsINode::eSVG))
|
||||
return NS_OK;
|
||||
|
||||
nsIScrollableView *scrollView;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
GetScrollInfo(&scrollView);
|
||||
|
||||
if (!scrollView) {
|
||||
nsRect rcFrame;
|
||||
nsCOMPtr<nsIContent> parent;
|
||||
(static_cast<nsGenericElement *>(mContent))->GetOffsetRect(rcFrame, getter_AddRefs(parent));
|
||||
*aScrollHeight = rcFrame.height;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// xMax and yMax is the total length of our container
|
||||
nscoord xMax, yMax;
|
||||
rv = scrollView->GetContainerSize(&xMax, &yMax);
|
||||
|
||||
*aScrollHeight = nsPresContext::AppUnitsToIntCSSPixels(yMax);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSElementTearoff::GetScrollWidth(PRInt32* aScrollWidth)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aScrollWidth);
|
||||
*aScrollWidth = 0;
|
||||
|
||||
if (mContent->IsNodeOfType(nsINode::eSVG))
|
||||
return NS_OK;
|
||||
|
||||
nsIScrollableView *scrollView;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
GetScrollInfo(&scrollView);
|
||||
|
||||
if (!scrollView) {
|
||||
nsRect rcFrame;
|
||||
nsCOMPtr<nsIContent> parent;
|
||||
(static_cast<nsGenericElement *>(mContent))->GetOffsetRect(rcFrame, getter_AddRefs(parent));
|
||||
*aScrollWidth = rcFrame.width;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nscoord xMax, yMax;
|
||||
rv = scrollView->GetContainerSize(&xMax, &yMax);
|
||||
|
||||
*aScrollWidth = nsPresContext::AppUnitsToIntCSSPixels(xMax);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsRect
|
||||
nsNSElementTearoff::GetClientAreaRect()
|
||||
{
|
||||
nsIScrollableView *scrollView;
|
||||
nsIFrame *frame;
|
||||
|
||||
// it isn't clear what to return for SVG nodes, so just return 0
|
||||
if (mContent->IsNodeOfType(nsINode::eSVG))
|
||||
return nsRect(0, 0, 0, 0);
|
||||
|
||||
GetScrollInfo(&scrollView, &frame);
|
||||
|
||||
if (scrollView) {
|
||||
return scrollView->View()->GetBounds();
|
||||
}
|
||||
|
||||
if (frame &&
|
||||
(frame->GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_INLINE ||
|
||||
frame->IsFrameOfType(nsIFrame::eReplaced))) {
|
||||
// Special case code to make client area work even when there isn't
|
||||
// a scroll view, see bug 180552, bug 227567.
|
||||
return frame->GetPaddingRect() - frame->GetPositionIgnoringScrolling();
|
||||
}
|
||||
|
||||
return nsRect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSElementTearoff::GetClientTop(PRInt32* aLength)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLength);
|
||||
*aLength = nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().y);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSElementTearoff::GetClientLeft(PRInt32* aLength)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLength);
|
||||
*aLength = nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().x);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSElementTearoff::GetClientHeight(PRInt32* aLength)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLength);
|
||||
*aLength = nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().height);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSElementTearoff::GetClientWidth(PRInt32* aLength)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLength);
|
||||
*aLength = nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().width);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsIFrame*
|
||||
GetContainingBlockForClientRect(nsIFrame* aFrame)
|
||||
{
|
||||
|
|
|
@ -78,8 +78,6 @@ class nsINodeInfo;
|
|||
class nsIControllers;
|
||||
class nsIDOMNSFeatureFactory;
|
||||
class nsIEventListenerManager;
|
||||
class nsIScrollableView;
|
||||
struct nsRect;
|
||||
|
||||
typedef unsigned long PtrBits;
|
||||
|
||||
|
@ -398,8 +396,6 @@ public:
|
|||
nsGenericElement(nsINodeInfo *aNodeInfo);
|
||||
virtual ~nsGenericElement();
|
||||
|
||||
friend class nsNSElementTearoff;
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
||||
/**
|
||||
|
@ -950,17 +946,6 @@ protected:
|
|||
*/
|
||||
virtual const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const;
|
||||
|
||||
/**
|
||||
* Retrieve the rectangle for the offsetX properties, which
|
||||
* are coordinates relative to the returned aOffsetParent.
|
||||
*
|
||||
* @param aRect offset rectangle
|
||||
* @param aOffsetParent offset parent
|
||||
*/
|
||||
virtual void GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent);
|
||||
|
||||
nsIFrame* GetStyledFrame();
|
||||
|
||||
public:
|
||||
// Because of a bug in MS C++ compiler nsDOMSlots must be declared public,
|
||||
// otherwise nsXULElement::nsXULSlots doesn't compile.
|
||||
|
@ -1142,24 +1127,6 @@ public:
|
|||
|
||||
private:
|
||||
nsRefPtr<nsGenericElement> mContent;
|
||||
|
||||
/**
|
||||
* Get this element's client area rect in app units.
|
||||
* @return the frame's client area
|
||||
*/
|
||||
nsRect GetClientAreaRect();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Get the element's styled frame (the primary frame or, for tables, the inner
|
||||
* table frame) and closest scrollable view.
|
||||
* @note This method flushes pending notifications (Flush_Layout).
|
||||
* @param aScrollableView the scrollable view [OUT]
|
||||
* @param aFrame (optional) the frame [OUT]
|
||||
*/
|
||||
void GetScrollInfo(nsIScrollableView **aScrollableView,
|
||||
nsIFrame **aFrame = nsnull);
|
||||
};
|
||||
|
||||
#endif /* nsGenericElement_h___ */
|
||||
|
|
|
@ -82,20 +82,6 @@ nsClientRect::GetBottom(float* aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClientRect::GetWidth(float* aResult)
|
||||
{
|
||||
*aResult = mWidth;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClientRect::GetHeight(float* aResult)
|
||||
{
|
||||
*aResult = mHeight;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_INTERFACE_TABLE_HEAD(nsClientRectList)
|
||||
NS_INTERFACE_TABLE1(nsClientRectList, nsIDOMClientRectList)
|
||||
NS_INTERFACE_TABLE_TO_MAP_SEGUE
|
||||
|
|
|
@ -116,6 +116,15 @@ class nsINodeInfo;
|
|||
class nsIDOMNodeList;
|
||||
class nsRuleWalker;
|
||||
|
||||
static nsIFrame*
|
||||
GetStyledFrameFor(nsGenericHTMLElement* aElement)
|
||||
{
|
||||
nsIFrame *frame = aElement->GetPrimaryFrame(Flush_Layout);
|
||||
|
||||
return (frame && frame->GetType() == nsGkAtoms::tableOuterFrame) ?
|
||||
frame->GetFirstChild(nsnull) : frame;
|
||||
}
|
||||
|
||||
// XXX todo: add in missing out-of-memory checks
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -488,9 +497,10 @@ void
|
|||
nsGenericHTMLElement::GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent)
|
||||
{
|
||||
*aOffsetParent = nsnull;
|
||||
aRect = nsRect();
|
||||
aRect.x = aRect.y = 0;
|
||||
aRect.Empty();
|
||||
|
||||
nsIFrame* frame = GetStyledFrame();
|
||||
nsIFrame* frame = ::GetStyledFrameFor(this);
|
||||
if (!frame) {
|
||||
return;
|
||||
}
|
||||
|
@ -753,6 +763,254 @@ nsGenericHTMLElement::SetInnerHTML(const nsAString& aInnerHTML)
|
|||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLElement::GetScrollInfo(nsIScrollableView **aScrollableView,
|
||||
nsIFrame **aFrame)
|
||||
{
|
||||
*aScrollableView = nsnull;
|
||||
|
||||
nsIFrame *frame = ::GetStyledFrameFor(this);
|
||||
if (aFrame) {
|
||||
*aFrame = frame;
|
||||
}
|
||||
if (!frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the scrollable frame
|
||||
nsIScrollableFrame *scrollFrame = nsnull;
|
||||
CallQueryInterface(frame, &scrollFrame);
|
||||
|
||||
if (!scrollFrame) {
|
||||
nsIScrollableViewProvider *scrollProvider = nsnull;
|
||||
CallQueryInterface(frame, &scrollProvider);
|
||||
if (scrollProvider) {
|
||||
*aScrollableView = scrollProvider->GetScrollableView();
|
||||
if (*aScrollableView) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool quirksMode = InNavQuirksMode(GetCurrentDoc());
|
||||
if ((quirksMode && mNodeInfo->Equals(nsGkAtoms::body)) ||
|
||||
(!quirksMode && mNodeInfo->Equals(nsGkAtoms::html))) {
|
||||
// In quirks mode, the scroll info for the body element should map to the
|
||||
// scroll info for the nearest scrollable frame above the body element
|
||||
// (i.e. the root scrollable frame). This is what IE6 does in quirks
|
||||
// mode. In strict mode the root scrollable frame corresponds to the
|
||||
// html element in IE6, so we map the scroll info for the html element to
|
||||
// the root scrollable frame.
|
||||
|
||||
do {
|
||||
frame = frame->GetParent();
|
||||
|
||||
if (!frame) {
|
||||
break;
|
||||
}
|
||||
|
||||
CallQueryInterface(frame, &scrollFrame);
|
||||
} while (!scrollFrame);
|
||||
}
|
||||
|
||||
if (!scrollFrame) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the scrollable view
|
||||
*aScrollableView = scrollFrame->GetScrollableView();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::GetScrollTop(PRInt32* aScrollTop)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aScrollTop);
|
||||
*aScrollTop = 0;
|
||||
|
||||
nsIScrollableView *view;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
GetScrollInfo(&view);
|
||||
|
||||
if (view) {
|
||||
nscoord xPos, yPos;
|
||||
rv = view->GetScrollPosition(xPos, yPos);
|
||||
|
||||
*aScrollTop = nsPresContext::AppUnitsToIntCSSPixels(yPos);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::SetScrollTop(PRInt32 aScrollTop)
|
||||
{
|
||||
nsIScrollableView *view;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
GetScrollInfo(&view);
|
||||
|
||||
if (view) {
|
||||
nscoord xPos, yPos;
|
||||
|
||||
rv = view->GetScrollPosition(xPos, yPos);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = view->ScrollTo(xPos, nsPresContext::CSSPixelsToAppUnits(aScrollTop),
|
||||
NS_VMREFRESH_IMMEDIATE);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::GetScrollLeft(PRInt32* aScrollLeft)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aScrollLeft);
|
||||
*aScrollLeft = 0;
|
||||
|
||||
nsIScrollableView *view;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
GetScrollInfo(&view);
|
||||
|
||||
if (view) {
|
||||
nscoord xPos, yPos;
|
||||
rv = view->GetScrollPosition(xPos, yPos);
|
||||
|
||||
*aScrollLeft = nsPresContext::AppUnitsToIntCSSPixels(xPos);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::SetScrollLeft(PRInt32 aScrollLeft)
|
||||
{
|
||||
nsIScrollableView *view;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
GetScrollInfo(&view);
|
||||
|
||||
if (view) {
|
||||
nscoord xPos, yPos;
|
||||
rv = view->GetScrollPosition(xPos, yPos);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = view->ScrollTo(nsPresContext::CSSPixelsToAppUnits(aScrollLeft),
|
||||
yPos, NS_VMREFRESH_IMMEDIATE);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::GetScrollHeight(PRInt32* aScrollHeight)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aScrollHeight);
|
||||
*aScrollHeight = 0;
|
||||
|
||||
nsIScrollableView *scrollView;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
GetScrollInfo(&scrollView);
|
||||
|
||||
if (!scrollView) {
|
||||
return GetOffsetHeight(aScrollHeight);
|
||||
}
|
||||
|
||||
// xMax and yMax is the total length of our container
|
||||
nscoord xMax, yMax;
|
||||
rv = scrollView->GetContainerSize(&xMax, &yMax);
|
||||
|
||||
*aScrollHeight = nsPresContext::AppUnitsToIntCSSPixels(yMax);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::GetScrollWidth(PRInt32* aScrollWidth)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aScrollWidth);
|
||||
*aScrollWidth = 0;
|
||||
|
||||
nsIScrollableView *scrollView;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
GetScrollInfo(&scrollView);
|
||||
|
||||
if (!scrollView) {
|
||||
return GetOffsetWidth(aScrollWidth);
|
||||
}
|
||||
|
||||
nscoord xMax, yMax;
|
||||
rv = scrollView->GetContainerSize(&xMax, &yMax);
|
||||
|
||||
*aScrollWidth = nsPresContext::AppUnitsToIntCSSPixels(xMax);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsRect
|
||||
nsGenericHTMLElement::GetClientAreaRect()
|
||||
{
|
||||
nsIScrollableView *scrollView;
|
||||
nsIFrame *frame;
|
||||
|
||||
GetScrollInfo(&scrollView, &frame);
|
||||
|
||||
if (scrollView) {
|
||||
return scrollView->View()->GetBounds();
|
||||
}
|
||||
|
||||
if (frame &&
|
||||
(frame->GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_INLINE ||
|
||||
frame->IsFrameOfType(nsIFrame::eReplaced))) {
|
||||
// Special case code to make client area work even when there isn't
|
||||
// a scroll view, see bug 180552, bug 227567.
|
||||
return frame->GetPaddingRect() - frame->GetPositionIgnoringScrolling();
|
||||
}
|
||||
|
||||
return nsRect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::GetClientTop(PRInt32* aLength)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLength);
|
||||
*aLength = nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().y);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::GetClientLeft(PRInt32* aLength)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLength);
|
||||
*aLength = nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().x);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::GetClientHeight(PRInt32* aLength)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLength);
|
||||
*aLength = nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().height);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::GetClientWidth(PRInt32* aLength)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLength);
|
||||
*aLength = nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().width);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::ScrollIntoView(PRBool aTop)
|
||||
{
|
||||
|
|
|
@ -58,6 +58,7 @@ class nsIURI;
|
|||
class nsIFormControlFrame;
|
||||
class nsIForm;
|
||||
class nsPresState;
|
||||
class nsIScrollableView;
|
||||
class nsILayoutHistoryState;
|
||||
class nsIEditor;
|
||||
struct nsRect;
|
||||
|
@ -144,6 +145,16 @@ public:
|
|||
nsresult GetOffsetParent(nsIDOMElement** aOffsetParent);
|
||||
virtual nsresult GetInnerHTML(nsAString& aInnerHTML);
|
||||
virtual nsresult SetInnerHTML(const nsAString& aInnerHTML);
|
||||
nsresult GetScrollTop(PRInt32* aScrollTop);
|
||||
nsresult SetScrollTop(PRInt32 aScrollTop);
|
||||
nsresult GetScrollLeft(PRInt32* aScrollLeft);
|
||||
nsresult SetScrollLeft(PRInt32 aScrollLeft);
|
||||
nsresult GetScrollHeight(PRInt32* aScrollHeight);
|
||||
nsresult GetScrollWidth(PRInt32* aScrollWidth);
|
||||
nsresult GetClientTop(PRInt32* aLength);
|
||||
nsresult GetClientLeft(PRInt32* aLength);
|
||||
nsresult GetClientHeight(PRInt32* aClientHeight);
|
||||
nsresult GetClientWidth(PRInt32* aClientWidth);
|
||||
nsresult ScrollIntoView(PRBool aTop);
|
||||
// Declare Focus(), Blur(), GetTabIndex(), SetTabIndex(), GetSpellcheck() and
|
||||
// SetSpellcheck() such that classes that inherit interfaces with those
|
||||
|
@ -157,6 +168,32 @@ public:
|
|||
nsresult GetContentEditable(nsAString &aContentEditable);
|
||||
nsresult SetContentEditable(const nsAString &aContentEditable);
|
||||
|
||||
/**
|
||||
* Get the frame's offset information for offsetTop/Left/Width/Height.
|
||||
* @note This method flushes pending notifications (Flush_Layout).
|
||||
* @param aRect the offset information [OUT]
|
||||
* @param aOffsetParent the parent the offset is relative to (offsetParent)
|
||||
* [OUT]
|
||||
*/
|
||||
void GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent);
|
||||
/**
|
||||
* Get the element's styled frame (the primary frame or, for tables, the inner
|
||||
* table frame) and closest scrollable view.
|
||||
* @note This method flushes pending notifications (Flush_Layout).
|
||||
* @param aScrollableView the scrollable view [OUT]
|
||||
* @param aFrame (optional) the frame [OUT]
|
||||
*/
|
||||
void GetScrollInfo(nsIScrollableView **aScrollableView,
|
||||
nsIFrame **aFrame = nsnull);
|
||||
|
||||
/**
|
||||
* Get this element's client area dimensions in app units.
|
||||
* The rect x, y, width, height are the clientLeft, clientTop, clientWidth,
|
||||
* clientHeight values.
|
||||
* @return the frame's client dimensions
|
||||
*/
|
||||
nsRect GetClientAreaRect();
|
||||
|
||||
// Implementation for nsIContent
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
|
@ -742,15 +779,6 @@ protected:
|
|||
*/
|
||||
virtual already_AddRefed<nsIEditor> GetAssociatedEditor();
|
||||
|
||||
/**
|
||||
* Get the frame's offset information for offsetTop/Left/Width/Height.
|
||||
* @note This method flushes pending notifications (Flush_Layout).
|
||||
* @param aRect the offset information [OUT]
|
||||
* @param aOffsetParent the parent the offset is relative to (offsetParent)
|
||||
* [OUT]
|
||||
*/
|
||||
virtual void GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent);
|
||||
|
||||
/**
|
||||
* Returns true if this is the current document's body element
|
||||
*/
|
||||
|
|
|
@ -38,13 +38,11 @@
|
|||
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(B2F824C4-D9D3-499B-8D3B-45C8245497C6)]
|
||||
[scriptable, uuid(f8583bbc-c6de-4646-b39f-df7e766442e9)]
|
||||
interface nsIDOMClientRect : nsISupports
|
||||
{
|
||||
readonly attribute float left;
|
||||
readonly attribute float top;
|
||||
readonly attribute float right;
|
||||
readonly attribute float bottom;
|
||||
readonly attribute float width;
|
||||
readonly attribute float height;
|
||||
};
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
interface nsIDOMNodeList;
|
||||
|
||||
[scriptable, uuid(A1901819-5EB1-41FF-B0E3-E1EC61E1BF1E)]
|
||||
[scriptable, uuid(cea6f919-7fe6-4bdd-9db6-158d9283f8d3)]
|
||||
interface nsIDOMNSElement : nsISupports
|
||||
{
|
||||
/*
|
||||
|
@ -69,7 +69,6 @@ interface nsIDOMNSElement : nsISupports
|
|||
* an empty list.
|
||||
*/
|
||||
nsIDOMClientRectList getClientRects();
|
||||
|
||||
/**
|
||||
* Returns the union of all rectangles in the getClientRects() list. Empty
|
||||
* rectangles are ignored, except that if all rectangles are empty,
|
||||
|
@ -77,53 +76,4 @@ interface nsIDOMNSElement : nsISupports
|
|||
* rectangle in getClientRects().
|
||||
*/
|
||||
nsIDOMClientRect getBoundingClientRect();
|
||||
|
||||
/**
|
||||
* The vertical scroll position of the element, or 0 if the element is not
|
||||
* scrollable. This property may be assigned a value to change the
|
||||
* vertical scroll position.
|
||||
*/
|
||||
attribute long scrollTop;
|
||||
|
||||
/**
|
||||
* The horizontal scroll position of the element, or 0 if the element is not
|
||||
* scrollable. This property may be assigned a value to change the
|
||||
* horizontal scroll position.
|
||||
*/
|
||||
attribute long scrollLeft;
|
||||
|
||||
/**
|
||||
* The height of the scrollable area of the element. If the element is not
|
||||
* scrollable, scrollHeight is equivalent to the offsetHeight.
|
||||
*/
|
||||
readonly attribute long scrollHeight;
|
||||
|
||||
/**
|
||||
* The width of the scrollable area of the element. If the element is not
|
||||
* scrollable, scrollWidth is equivalent to the offsetWidth.
|
||||
*/
|
||||
readonly attribute long scrollWidth;
|
||||
|
||||
/**
|
||||
* The height in CSS pixels of the element's top border.
|
||||
*/
|
||||
readonly attribute long clientTop;
|
||||
|
||||
/**
|
||||
* The width in CSS pixels of the element's left border and scrollbar
|
||||
* if it is present on the left side.
|
||||
*/
|
||||
readonly attribute long clientLeft;
|
||||
|
||||
/**
|
||||
* The width in CSS pixels of the element's padding box. If the element is
|
||||
* scrollable, the scroll bars are included inside this height.
|
||||
*/
|
||||
readonly attribute long clientHeight;
|
||||
|
||||
/**
|
||||
* The height in CSS pixels of the element's padding box. If the element is
|
||||
* scrollable, the scroll bars are included inside this width.
|
||||
*/
|
||||
readonly attribute long clientWidth;
|
||||
};
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(5D090306-86AA-43F8-A78F-7346084DA4C5)]
|
||||
[scriptable, uuid(eac0a4ee-2e4f-403c-9b77-5cf32cfb42f7)]
|
||||
interface nsIDOMNSHTMLElement : nsISupports
|
||||
{
|
||||
readonly attribute long offsetTop;
|
||||
|
@ -48,6 +48,16 @@ interface nsIDOMNSHTMLElement : nsISupports
|
|||
readonly attribute nsIDOMElement offsetParent;
|
||||
attribute DOMString innerHTML;
|
||||
|
||||
attribute long scrollTop;
|
||||
attribute long scrollLeft;
|
||||
readonly attribute long scrollHeight;
|
||||
readonly attribute long scrollWidth;
|
||||
|
||||
readonly attribute long clientTop;
|
||||
readonly attribute long clientLeft;
|
||||
readonly attribute long clientHeight;
|
||||
readonly attribute long clientWidth;
|
||||
|
||||
attribute long tabIndex;
|
||||
|
||||
attribute DOMString contentEditable;
|
||||
|
|
|
@ -49,7 +49,6 @@ DIRS += \
|
|||
ajax \
|
||||
bugs \
|
||||
chrome \
|
||||
general \
|
||||
whatwg \
|
||||
geolocation \
|
||||
$(NULL)
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = dom/tests/mochitest/general
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = test_offsets.html \
|
||||
test_offsets.xul \
|
||||
test_offsets.js \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
|
|
@ -1,87 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html style="margin: 5px; border: 0; padding: 1px;">
|
||||
<head>
|
||||
<title>HTML Tests for offset/client/scroll properties</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="test_offsets.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
|
||||
|
||||
</head>
|
||||
<body id="body" onload="setTimeout(testElements, 0, 'testelements', SimpleTest.finish);"
|
||||
style="margin: 1px; border: 2px solid black; padding: 4px;">
|
||||
|
||||
<div id="testelements" style="margin: 0; border: 0; padding: 0;">
|
||||
<input id="input1" style="margin: 0; margin-left: 6px; margin-top: 2px; border: 1px solid green; padding: 6px; width: 50px; height: 20px"
|
||||
_offsetLeft="13" _offsetTop="9" _offsetWidth="64" _offsetHeight="34"
|
||||
_scrollWidth="62" _scrollHeight="32"
|
||||
_clientLeft="1" _clientTop="1" _clientWidth="62" _clientHeight="32">
|
||||
<div id="noscroll" style="margin: 2px; border: 1px solid blue; padding: 3px;"
|
||||
_offsetLeft="10" _offsetTop="12" _offsetWidth="64" _offsetHeight="34"
|
||||
_scrollWidth="62" _scrollHeight="32"
|
||||
_clientLeft="1" _clientTop="1" _clientWidth="62" _clientHeight="32">
|
||||
<div id="inner">Inner Text</div>
|
||||
</div>
|
||||
|
||||
<div id="absolute" style="position: absolute; margin: 5px; border: 2px solid blue; padding: 0;">
|
||||
<div id="absolute-block" _offsetParent="absolute">
|
||||
<input id="absolute-replaced" _offsetParent="absolute" style="margin: 1px; border: 0; padding: 3px;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="absolutelr" style="position: absolute; margin: 5px; border: 2px solid blue; padding: 0; left: 90px; top: 130px;">
|
||||
This is some absolute positioned text.
|
||||
<div id="absolutelr-block" _offsetParent="absolutelr">
|
||||
<input id="absolutelr-replaced" _offsetParent="absolutelr" style="margin: 1px; border: 0; padding: 3px;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="relative" style="position: relative; margin: 2px; border: 1px solid orange; padding: 7px; left: 10px; top: 5px;">
|
||||
This is some relative positioned text.
|
||||
<div id="relative-block" _offsetParent="relative">
|
||||
<input id="relative-replaced" _offsetParent="relative" style="margin: 1px; border: 0; padding: 3px;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="fixed" style="position: fixed; margin: 2px; border: 1px solid orange; padding: 7px; left: 87px; top: 12px;">
|
||||
This is some fixed positioned text.
|
||||
<div id="fixed-block" _offsetParent="fixed">
|
||||
<input id="fixed-replaced" _offsetParent="fixed" style="margin: 1px; border: 0; padding: 3px;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="scrollbox"
|
||||
style="overflow: scroll; padding-left: 0px; margin: 3px; border: 4px solid green; max-width: 80px; max-height: 70px;"
|
||||
_scrollWidth="62" _scrollHeight="32"
|
||||
_clientLeft="1" _clientTop="1" _clientWidth="62" _clientHeight="32"><p id="p1" style="margin: 0; padding: 0;">One</p>
|
||||
<p id="p2">Two</p>
|
||||
<p id="scrollchild">Three</p>
|
||||
<p id="lastlinebox" style="margin: 0; padding: 0;"><input id="lastline" type="button"
|
||||
style="margin: 0px; border: 2px solid red;"
|
||||
value="This button is much longer than the others">
|
||||
</p></div>
|
||||
|
||||
<input id="input-displaynone" style="display: none; border: 0; padding: 0;"
|
||||
_offsetParent="null">
|
||||
<p id="p3" style="margin: 2px; border: 0; padding: 1px;"
|
||||
_offsetLeft="9" _offsetTop="9" _offsetWidth="64" _offsetHeight="34"
|
||||
_scrollWidth="62" _scrollHeight="32"
|
||||
_clientLeft="1" _clientTop="1" _clientWidth="62" _clientHeight="32">
|
||||
<input id="input-nosize" style="width: 0; height: 0; margin: 0; border: 0; padding: 0;">
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="scrollbox-test" style="float: left; overflow: scroll; margin: 0; border: 0; padding: 0"></div>
|
||||
|
||||
<script type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,192 +0,0 @@
|
|||
var scrollbarWidth = 17, scrollbarHeight = 17;
|
||||
|
||||
function testElements(baseid, callback)
|
||||
{
|
||||
scrollbarWidth = scrollbarHeight = gcs($("scrollbox-test"), "width");
|
||||
|
||||
var elements = $(baseid).getElementsByTagName("*");
|
||||
for (var t = 0; t < elements.length; t++) {
|
||||
var element = elements[t];
|
||||
testElement(element);
|
||||
}
|
||||
|
||||
var nonappended = document.createElement("div");
|
||||
nonappended.id = "nonappended";
|
||||
nonappended.setAttribute("_offsetParent", "null");
|
||||
testElement(nonappended);
|
||||
|
||||
checkScrolledElement($("scrollbox"), $("scrollchild"));
|
||||
|
||||
var div = $("noscroll");
|
||||
div.scrollLeft = 10;
|
||||
div.scrollTop = 10;
|
||||
is(element.scrollLeft, 0, element.id + " scrollLeft after nonscroll");
|
||||
is(element.scrollTop, 0, element.id + " scrollTop after nonscroll");
|
||||
|
||||
callback();
|
||||
}
|
||||
|
||||
function testElement(element)
|
||||
{
|
||||
var offsetParent = element.getAttribute("_offsetParent");
|
||||
offsetParent = $(offsetParent == "null" ? null: (offsetParent ? offsetParent : "body"));
|
||||
|
||||
var borderLeft = gcs(element, "borderLeftWidth");
|
||||
var borderTop = gcs(element, "borderTopWidth");
|
||||
var borderRight = gcs(element, "borderRightWidth");
|
||||
var borderBottom = gcs(element, "borderBottomWidth");
|
||||
var paddingLeft = gcs(element, "paddingLeft");
|
||||
var paddingTop = gcs(element, "paddingTop");
|
||||
var paddingRight = gcs(element, "paddingRight");
|
||||
var paddingBottom = gcs(element, "paddingBottom");
|
||||
var width = gcs(element, "width");
|
||||
var height = gcs(element, "height");
|
||||
|
||||
if (element instanceof HTMLElement)
|
||||
checkOffsetState(element, -10000, -10000,
|
||||
borderLeft + paddingLeft + width + paddingRight + borderRight,
|
||||
borderTop + paddingTop + height + paddingBottom + borderBottom,
|
||||
offsetParent, element.id);
|
||||
|
||||
var scrollWidth, scrollHeight, clientWidth, clientHeight;
|
||||
if (element.id == "scrollbox") {
|
||||
var lastchild = $("lastline");
|
||||
scrollWidth = Math.round(lastchild.getBoundingClientRect().width) + paddingLeft + paddingRight;
|
||||
scrollHeight = Math.round(element.lastChild.getBoundingClientRect().bottom) -
|
||||
Math.round(element.firstChild.getBoundingClientRect().top) + paddingTop + paddingBottom;
|
||||
clientWidth = paddingLeft + width + paddingRight - scrollbarWidth;
|
||||
clientHeight = paddingTop + height + paddingBottom - scrollbarHeight;
|
||||
}
|
||||
else {
|
||||
// XXXndeakin note that Mozilla adds borders here, although the spec does not
|
||||
scrollWidth = paddingLeft + width + paddingRight + borderLeft + borderRight;
|
||||
scrollHeight = paddingTop + height + paddingBottom + borderTop + borderBottom;
|
||||
clientWidth = paddingLeft + width + paddingRight;
|
||||
clientHeight = paddingTop + height + paddingBottom;
|
||||
}
|
||||
|
||||
if (element instanceof SVGElement)
|
||||
checkScrollState(element, 0, 0, 0, 0, element.id);
|
||||
else
|
||||
checkScrollState(element, 0, 0, scrollWidth, scrollHeight, element.id);
|
||||
|
||||
if (element instanceof SVGElement)
|
||||
checkClientState(element, 0, 0, 0, 0, element.id);
|
||||
else
|
||||
checkClientState(element, borderLeft, borderTop, clientWidth, clientHeight, element.id);
|
||||
|
||||
var boundingrect = element.getBoundingClientRect();
|
||||
is(Math.round(boundingrect.width), borderLeft + paddingLeft + width + paddingRight + borderLeft,
|
||||
element.id + " bounding rect width");
|
||||
is(Math.round(boundingrect.height), borderTop + paddingTop + height + paddingBottom + borderBottom,
|
||||
element.id + " bounding rect height");
|
||||
is(Math.round(boundingrect.right - boundingrect.left),
|
||||
borderLeft + paddingLeft + width + paddingRight + borderLeft,
|
||||
element.id + " bounding rect right");
|
||||
is(Math.round(boundingrect.bottom - boundingrect.top),
|
||||
borderTop + paddingTop + height + paddingBottom + borderBottom,
|
||||
element.id + " bounding rect bottom");
|
||||
|
||||
var rects = element.getClientRects();
|
||||
if (element.id == "input-displaynone" || element.id == "nonappended") {
|
||||
is(rects.length, 0, element.id + " getClientRects empty");
|
||||
}
|
||||
else {
|
||||
is(rects[0].left, boundingrect.left, element.id + " getClientRects left");
|
||||
is(rects[0].top, boundingrect.top, element.id + " getClientRects top");
|
||||
is(rects[0].right, boundingrect.right, element.id + " getClientRects right");
|
||||
is(rects[0].bottom, boundingrect.bottom, element.id + " getClientRects bottom");
|
||||
}
|
||||
|
||||
var root = document.documentElement;
|
||||
gPreviousRight = Math.round(boundingrect.right) -
|
||||
gcs(root, "paddingLeft") - gcs(root, "borderLeftWidth");
|
||||
gPreviousBottom = Math.round(boundingrect.bottom) -
|
||||
gcs(root, "paddingTop") - gcs(root, "borderTopWidth");
|
||||
}
|
||||
|
||||
function checkScrolledElement(element, child)
|
||||
{
|
||||
var elemrect = element.getBoundingClientRect();
|
||||
var childrect = child.getBoundingClientRect();
|
||||
|
||||
var topdiff = childrect.top - elemrect.top;
|
||||
|
||||
element.scrollTop = 20;
|
||||
is(element.scrollLeft, 0, element.id + " scrollLeft after vertical scroll");
|
||||
is(element.scrollTop, 20, element.id + " scrollTop after vertical scroll");
|
||||
is(child.getBoundingClientRect().top, childrect.top - 20, "child position after vertical scroll");
|
||||
|
||||
element.scrollTop = 0;
|
||||
is(element.scrollLeft, 0, element.id + " scrollLeft after vertical scroll reset");
|
||||
is(element.scrollTop, 0, element.id + " scrollTop after vertical scroll reset");
|
||||
is(child.getBoundingClientRect().top, childrect.top, "child position after vertical scroll reset");
|
||||
|
||||
element.scrollTop = 10;
|
||||
element.scrollTop = -30;
|
||||
is(element.scrollLeft, 0, element.id + " scrollLeft after vertical scroll negative");
|
||||
is(element.scrollTop, 0, element.id + " scrollTop after vertical scroll negative");
|
||||
is(child.getBoundingClientRect().top, childrect.top, "child position after vertical scroll negative");
|
||||
|
||||
element.scrollLeft = 18;
|
||||
is(element.scrollLeft, 18, element.id + " scrollLeft after horizontal scroll");
|
||||
is(element.scrollTop, 0, element.id + " scrollTop after horizontal scroll");
|
||||
is(child.getBoundingClientRect().left, childrect.left - 18, "child position after horizontal scroll");
|
||||
|
||||
element.scrollLeft = -30;
|
||||
is(element.scrollLeft, 0, element.id + " scrollLeft after horizontal scroll reset");
|
||||
is(element.scrollTop, 0, element.id + " scrollTop after horizontal scroll reset");
|
||||
is(child.getBoundingClientRect().left, childrect.left, "child position after horizontal scroll reset");
|
||||
}
|
||||
|
||||
function checkOffsetState(element, left, top, width, height, parent, testname)
|
||||
{
|
||||
checkCoords(element, "offset", left, top, width, height, testname);
|
||||
is(element.offsetParent, parent, testname + " offsetParent");
|
||||
}
|
||||
|
||||
function checkScrollState(element, left, top, width, height, testname)
|
||||
{
|
||||
checkCoords(element, "scroll", left, top, width, height, testname);
|
||||
}
|
||||
|
||||
function checkClientState(element, left, top, width, height, testname)
|
||||
{
|
||||
checkCoords(element, "client", left, top, width, height, testname);
|
||||
}
|
||||
|
||||
function checkCoord(element, type, val, testname)
|
||||
{
|
||||
if (val != -10000)
|
||||
is(element[type], val, testname + " " + type);
|
||||
}
|
||||
|
||||
function checkCoords(element, type, left, top, width, height, testname)
|
||||
{
|
||||
checkCoord(element, type + "Left", left, testname);
|
||||
checkCoord(element, type + "Top", top, testname);
|
||||
checkCoord(element, type + "Width", width, testname);
|
||||
checkCoord(element, type + "Height", height, testname);
|
||||
|
||||
if (element instanceof SVGElement)
|
||||
return;
|
||||
|
||||
if (element.id == "outerpopup" && !element.parentNode.open) // closed popup
|
||||
return;
|
||||
|
||||
if (element.id == "input-displaynone" || element.id == "nonappended") // hidden elements
|
||||
ok(element[type + "Width"] == 0 && element[type + "Height"] == 0,
|
||||
element.id + " has zero " + type + " width and height");
|
||||
else if (element.id != "input-nosize") // for some reason, this element has a width of 2
|
||||
ok(element[type + "Width"] > 0 && element[type + "Height"] > 0,
|
||||
element.id + " has non-zero " + type + " width and height");
|
||||
}
|
||||
|
||||
function gcs(element, prop)
|
||||
{
|
||||
var prop = getComputedStyle(element, "")[prop];
|
||||
if (prop == "auto")
|
||||
prop = 0;
|
||||
var propFloat = parseFloat(prop);
|
||||
return (isNaN(propFloat) ? prop : Math.round(propFloat));
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
|
||||
<!--
|
||||
XUL Tests for client/scroll properties
|
||||
-->
|
||||
<window title="Test Offset/Client/Scroll Properties" width="500" height="600"
|
||||
onload="setTimeout(testElements, 0, 'testelements', doneTests);"
|
||||
style="margin: 1px !important"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"/>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="text/javascript" src="test_offsets.js"/>
|
||||
|
||||
<vbox id="testelements" style="margin: 0; padding: 0; border: 0;">
|
||||
<vbox id="vbox" style="margin: 5px 0 0 2px;">
|
||||
<vbox id="noscroll" align="start">
|
||||
<button id="button1" label="Button One" style="margin: 0px; padding: 0; border: 0;"/>
|
||||
<button id="button2" label="Button Two" width="140" height="120"/>
|
||||
</vbox>
|
||||
<hbox align="start">
|
||||
<vbox id="scrollbox" style="overflow: scroll; padding: 2px; margin: 3px; border: 4px solid green;"
|
||||
maxwidth="60" maxheight="50">
|
||||
<label value="One" style="margin: 0"/>
|
||||
<label id="scrollchild" value="Two"/>
|
||||
<label value="Three"/>
|
||||
<label id="lastline" value="This fourth label is much longer than the others"
|
||||
style="margin: 0; padding: 0; border: 0;"/>
|
||||
</vbox>
|
||||
<scrollbar id="scrollbox-test" orient="vertical" style="margin: 0; border: 0; padding: 0"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
||||
<svg:svg id="svgbase" width="45" height="20" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<svg:rect id="svgrect" x="3" y="5" width="45" height="20" fill="red"/>
|
||||
</svg:svg>
|
||||
|
||||
</vbox>
|
||||
|
||||
<button id="outermenu" type="menu" label="Menu">
|
||||
<menupopup id="outerpopup"
|
||||
style="margin-left: 5px; padding-left: 3px; padding: 0;"
|
||||
onpopupshown="this.firstChild.open = true"
|
||||
onpopuphidden="if (event.target == this) SimpleTest.finish();">
|
||||
<menu id="innermenu" label="Open"
|
||||
style="margin: 0; padding: 0; border: 2px black solid; -moz-appearance: none;">
|
||||
<menupopup style="margin: 0; padding: 0; border: 1px black solid; -moz-appearance: none;"
|
||||
onpopupshown="testElements('outermenu', doneTests)">
|
||||
<menuitem label="Document"/>
|
||||
<menuitem id="innermenuitem" style="margin: 2px; padding: 3px;" label="Page"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuitem id="outermenuitem" label="Close"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
|
||||
<!-- test resuls are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
|
||||
var gTestSet = "box";
|
||||
|
||||
var whichpopup = "outer";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function doneTests()
|
||||
{
|
||||
if (gTestSet == "box") {
|
||||
gTestSet = "popup";
|
||||
// only test this on Mac for now
|
||||
if (navigator.platform.indexOf("Mac") >= 0) {
|
||||
checkScrollState($("outerpopup"), 0, 0, 0, 0, "popup before open");
|
||||
checkClientState($("outerpopup"), 0, 0, 0, 0, "popup before open");
|
||||
}
|
||||
$("outermenu").open = true;
|
||||
}
|
||||
else {
|
||||
$("outermenu").open = false;
|
||||
}
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
</window>
|
Загрузка…
Ссылка в новой задаче