Backed out changeset 2e8dfe209f09 due to unit test bustage

This commit is contained in:
Ted Mielczarek 2008-08-15 12:59:30 -04:00
Родитель 944e99b67e
Коммит 1fef5b8148
13 изменённых файлов: 310 добавлений и 849 удалений

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

@ -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>