Backed out 8 changesets (bug 917755) for bustage making inbound a CLOSED TREE.
Backed out changeset 98e31d225a5a (bug 917755) Backed out changeset 43bceca43fb6 (bug 917755) Backed out changeset 5117e3f594e7 (bug 917755) Backed out changeset ada41f2f74b8 (bug 917755) Backed out changeset 5272cfbd63f3 (bug 917755) Backed out changeset f3bbd98021f7 (bug 917755) Backed out changeset b049571a7cce (bug 917755) Backed out changeset 472cb7738e14 (bug 917755)
This commit is contained in:
@@ -66,8 +66,6 @@ inline bool IsSpaceCharacter(char aChar) {
|
|||||||
aChar == '\f';
|
aChar == '\f';
|
||||||
}
|
}
|
||||||
class Element;
|
class Element;
|
||||||
struct BoxQuadOptions;
|
|
||||||
class DOMQuad;
|
|
||||||
class EventHandlerNonNull;
|
class EventHandlerNonNull;
|
||||||
class OnErrorEventHandlerNonNull;
|
class OnErrorEventHandlerNonNull;
|
||||||
template<typename T> class Optional;
|
template<typename T> class Optional;
|
||||||
@@ -281,10 +279,6 @@ private:
|
|||||||
class nsINode : public mozilla::dom::EventTarget
|
class nsINode : public mozilla::dom::EventTarget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef mozilla::dom::BoxQuadOptions BoxQuadOptions;
|
|
||||||
typedef mozilla::dom::DOMQuad DOMQuad;
|
|
||||||
typedef mozilla::ErrorResult ErrorResult;
|
|
||||||
|
|
||||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODE_IID)
|
NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODE_IID)
|
||||||
|
|
||||||
// Among the sub-classes that inherit (directly or indirectly) from nsINode,
|
// Among the sub-classes that inherit (directly or indirectly) from nsINode,
|
||||||
@@ -1616,10 +1610,6 @@ public:
|
|||||||
mozilla::dom::Element* GetFirstElementChild() const;
|
mozilla::dom::Element* GetFirstElementChild() const;
|
||||||
mozilla::dom::Element* GetLastElementChild() const;
|
mozilla::dom::Element* GetLastElementChild() const;
|
||||||
|
|
||||||
void GetBoxQuads(const BoxQuadOptions& aOptions,
|
|
||||||
nsTArray<nsRefPtr<DOMQuad> >& aResult,
|
|
||||||
mozilla::ErrorResult& aRv);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Override this function to create a custom slots class.
|
// Override this function to create a custom slots class.
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "mozilla/dom/DOMPoint.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/DOMPointBinding.h"
|
|
||||||
#include "mozilla/dom/BindingDeclarations.h"
|
|
||||||
#include "nsAutoPtr.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
|
||||||
using namespace mozilla::dom;
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(DOMPoint, mParent)
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMPoint, AddRef)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMPoint, Release)
|
|
||||||
|
|
||||||
already_AddRefed<DOMPoint>
|
|
||||||
DOMPoint::Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams,
|
|
||||||
ErrorResult& aRV)
|
|
||||||
{
|
|
||||||
nsRefPtr<DOMPoint> obj =
|
|
||||||
new DOMPoint(aGlobal.GetAsSupports(), aParams.mX, aParams.mY,
|
|
||||||
aParams.mZ, aParams.mW);
|
|
||||||
return obj.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<DOMPoint>
|
|
||||||
DOMPoint::Constructor(const GlobalObject& aGlobal, double aX, double aY,
|
|
||||||
double aZ, double aW, ErrorResult& aRV)
|
|
||||||
{
|
|
||||||
nsRefPtr<DOMPoint> obj =
|
|
||||||
new DOMPoint(aGlobal.GetAsSupports(), aX, aY, aZ, aW);
|
|
||||||
return obj.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
JSObject*
|
|
||||||
DOMPoint::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
|
|
||||||
{
|
|
||||||
return DOMPointBinding::Wrap(aCx, aScope, this);
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef MOZILLA_DOMPOINT_H_
|
|
||||||
#define MOZILLA_DOMPOINT_H_
|
|
||||||
|
|
||||||
#include "nsWrapperCache.h"
|
|
||||||
#include "nsISupports.h"
|
|
||||||
#include "nsCycleCollectionParticipant.h"
|
|
||||||
#include "mozilla/Attributes.h"
|
|
||||||
#include "mozilla/ErrorResult.h"
|
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
#include "mozilla/dom/BindingDeclarations.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace dom {
|
|
||||||
|
|
||||||
class GlobalObject;
|
|
||||||
class DOMPointInit;
|
|
||||||
|
|
||||||
class DOMPointReadOnly : public nsWrapperCache
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DOMPointReadOnly(nsISupports* aParent, double aX, double aY,
|
|
||||||
double aZ, double aW)
|
|
||||||
: mParent(aParent)
|
|
||||||
, mX(aX)
|
|
||||||
, mY(aY)
|
|
||||||
, mZ(aZ)
|
|
||||||
, mW(aW)
|
|
||||||
{
|
|
||||||
SetIsDOMBinding();
|
|
||||||
}
|
|
||||||
|
|
||||||
double X() const { return mX; }
|
|
||||||
double Y() const { return mY; }
|
|
||||||
double Z() const { return mZ; }
|
|
||||||
double W() const { return mW; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
nsCOMPtr<nsISupports> mParent;
|
|
||||||
double mX, mY, mZ, mW;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DOMPoint MOZ_FINAL : public DOMPointReadOnly
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DOMPoint(nsISupports* aParent, double aX = 0.0, double aY = 0.0,
|
|
||||||
double aZ = 0.0, double aW = 1.0)
|
|
||||||
: DOMPointReadOnly(aParent, aX, aY, aZ, aW)
|
|
||||||
{}
|
|
||||||
|
|
||||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMPoint)
|
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMPoint)
|
|
||||||
|
|
||||||
static already_AddRefed<DOMPoint>
|
|
||||||
Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams,
|
|
||||||
ErrorResult& aRV);
|
|
||||||
static already_AddRefed<DOMPoint>
|
|
||||||
Constructor(const GlobalObject& aGlobal, double aX, double aY,
|
|
||||||
double aZ, double aW, ErrorResult& aRV);
|
|
||||||
|
|
||||||
nsISupports* GetParentObject() const { return mParent; }
|
|
||||||
virtual JSObject* WrapObject(JSContext* aCx,
|
|
||||||
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
void SetX(double aX) { mX = aX; }
|
|
||||||
void SetY(double aY) { mY = aY; }
|
|
||||||
void SetZ(double aZ) { mZ = aZ; }
|
|
||||||
void SetW(double aW) { mW = aW; }
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /*MOZILLA_DOMPOINT_H_*/
|
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "mozilla/dom/DOMQuad.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/DOMQuadBinding.h"
|
|
||||||
#include "mozilla/dom/DOMPoint.h"
|
|
||||||
#include "mozilla/dom/DOMRect.h"
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
using namespace mozilla;
|
|
||||||
using namespace mozilla::dom;
|
|
||||||
using namespace mozilla::gfx;
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_6(DOMQuad, mParent, mBounds, mPoints[0],
|
|
||||||
mPoints[1], mPoints[2], mPoints[3])
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMQuad, AddRef)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMQuad, Release)
|
|
||||||
|
|
||||||
DOMQuad::DOMQuad(nsISupports* aParent, CSSPoint aPoints[4])
|
|
||||||
: mParent(aParent)
|
|
||||||
{
|
|
||||||
SetIsDOMBinding();
|
|
||||||
for (uint32_t i = 0; i < 4; ++i) {
|
|
||||||
mPoints[i] = new DOMPoint(aParent, aPoints[i].x, aPoints[i].y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DOMQuad::DOMQuad(nsISupports* aParent)
|
|
||||||
: mParent(aParent)
|
|
||||||
{
|
|
||||||
SetIsDOMBinding();
|
|
||||||
}
|
|
||||||
|
|
||||||
DOMQuad::~DOMQuad()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
JSObject*
|
|
||||||
DOMQuad::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
|
|
||||||
{
|
|
||||||
return DOMQuadBinding::Wrap(aCx, aScope, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<DOMQuad>
|
|
||||||
DOMQuad::Constructor(const GlobalObject& aGlobal,
|
|
||||||
const DOMPointInit& aP1,
|
|
||||||
const DOMPointInit& aP2,
|
|
||||||
const DOMPointInit& aP3,
|
|
||||||
const DOMPointInit& aP4,
|
|
||||||
ErrorResult& aRV)
|
|
||||||
{
|
|
||||||
nsRefPtr<DOMQuad> obj = new DOMQuad(aGlobal.GetAsSupports());
|
|
||||||
obj->mPoints[0] = DOMPoint::Constructor(aGlobal, aP1, aRV);
|
|
||||||
obj->mPoints[1] = DOMPoint::Constructor(aGlobal, aP2, aRV);
|
|
||||||
obj->mPoints[2] = DOMPoint::Constructor(aGlobal, aP3, aRV);
|
|
||||||
obj->mPoints[3] = DOMPoint::Constructor(aGlobal, aP4, aRV);
|
|
||||||
return obj.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<DOMQuad>
|
|
||||||
DOMQuad::Constructor(const GlobalObject& aGlobal, const DOMRectReadOnly& aRect,
|
|
||||||
ErrorResult& aRV)
|
|
||||||
{
|
|
||||||
CSSPoint points[4];
|
|
||||||
Float x = aRect.X(), y = aRect.Y(), w = aRect.Width(), h = aRect.Height();
|
|
||||||
points[0] = CSSPoint(x, y);
|
|
||||||
points[1] = CSSPoint(x + w, y);
|
|
||||||
points[2] = CSSPoint(x + w, y + h);
|
|
||||||
points[3] = CSSPoint(x, y + h);
|
|
||||||
nsRefPtr<DOMQuad> obj = new DOMQuad(aGlobal.GetAsSupports(), points);
|
|
||||||
return obj.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
class DOMQuad::QuadBounds MOZ_FINAL : public DOMRectReadOnly
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QuadBounds(DOMQuad* aQuad)
|
|
||||||
: DOMRectReadOnly(aQuad->GetParentObject())
|
|
||||||
, mQuad(aQuad)
|
|
||||||
{}
|
|
||||||
|
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(QuadBounds, DOMRectReadOnly)
|
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
|
||||||
|
|
||||||
virtual double X() const
|
|
||||||
{
|
|
||||||
double x1, x2;
|
|
||||||
GetHorizontalMinMax(&x1, &x2);
|
|
||||||
return x1;
|
|
||||||
}
|
|
||||||
virtual double Y() const
|
|
||||||
{
|
|
||||||
double y1, y2;
|
|
||||||
GetVerticalMinMax(&y1, &y2);
|
|
||||||
return y1;
|
|
||||||
}
|
|
||||||
virtual double Width() const
|
|
||||||
{
|
|
||||||
double x1, x2;
|
|
||||||
GetHorizontalMinMax(&x1, &x2);
|
|
||||||
return x2 - x1;
|
|
||||||
}
|
|
||||||
virtual double Height() const
|
|
||||||
{
|
|
||||||
double y1, y2;
|
|
||||||
GetVerticalMinMax(&y1, &y2);
|
|
||||||
return y2 - y1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetHorizontalMinMax(double* aX1, double* aX2) const
|
|
||||||
{
|
|
||||||
double x1, x2;
|
|
||||||
x1 = x2 = mQuad->Point(0)->X();
|
|
||||||
for (uint32_t i = 1; i < 4; ++i) {
|
|
||||||
double x = mQuad->Point(i)->X();
|
|
||||||
x1 = std::min(x1, x);
|
|
||||||
x2 = std::max(x2, x);
|
|
||||||
}
|
|
||||||
*aX1 = x1;
|
|
||||||
*aX2 = x2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetVerticalMinMax(double* aY1, double* aY2) const
|
|
||||||
{
|
|
||||||
double y1, y2;
|
|
||||||
y1 = y2 = mQuad->Point(0)->Y();
|
|
||||||
for (uint32_t i = 1; i < 4; ++i) {
|
|
||||||
double y = mQuad->Point(i)->Y();
|
|
||||||
y1 = std::min(y1, y);
|
|
||||||
y2 = std::max(y2, y);
|
|
||||||
}
|
|
||||||
*aY1 = y1;
|
|
||||||
*aY2 = y2;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
nsRefPtr<DOMQuad> mQuad;
|
|
||||||
};
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(DOMQuad::QuadBounds, DOMRectReadOnly, mQuad)
|
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMQuad::QuadBounds)
|
|
||||||
NS_INTERFACE_MAP_END_INHERITING(DOMRectReadOnly)
|
|
||||||
|
|
||||||
NS_IMPL_ADDREF_INHERITED(DOMQuad::QuadBounds, DOMRectReadOnly)
|
|
||||||
NS_IMPL_RELEASE_INHERITED(DOMQuad::QuadBounds, DOMRectReadOnly)
|
|
||||||
|
|
||||||
DOMRectReadOnly*
|
|
||||||
DOMQuad::Bounds() const
|
|
||||||
{
|
|
||||||
if (!mBounds) {
|
|
||||||
mBounds = new QuadBounds(const_cast<DOMQuad*>(this));
|
|
||||||
}
|
|
||||||
return mBounds;
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef MOZILLA_DOMQUAD_H_
|
|
||||||
#define MOZILLA_DOMQUAD_H_
|
|
||||||
|
|
||||||
#include "nsWrapperCache.h"
|
|
||||||
#include "nsISupports.h"
|
|
||||||
#include "nsCycleCollectionParticipant.h"
|
|
||||||
#include "mozilla/Attributes.h"
|
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
#include "nsAutoPtr.h"
|
|
||||||
#include "mozilla/dom/BindingDeclarations.h"
|
|
||||||
#include "mozilla/ErrorResult.h"
|
|
||||||
#include "Units.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace dom {
|
|
||||||
|
|
||||||
class DOMRectReadOnly;
|
|
||||||
class DOMPoint;
|
|
||||||
struct DOMPointInit;
|
|
||||||
|
|
||||||
class DOMQuad MOZ_FINAL : public nsWrapperCache
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DOMQuad(nsISupports* aParent, CSSPoint aPoints[4]);
|
|
||||||
DOMQuad(nsISupports* aParent);
|
|
||||||
~DOMQuad();
|
|
||||||
|
|
||||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMQuad)
|
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMQuad)
|
|
||||||
|
|
||||||
nsISupports* GetParentObject() const { return mParent; }
|
|
||||||
virtual JSObject* WrapObject(JSContext* aCx,
|
|
||||||
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
static already_AddRefed<DOMQuad>
|
|
||||||
Constructor(const GlobalObject& aGlobal,
|
|
||||||
const DOMPointInit& aP1,
|
|
||||||
const DOMPointInit& aP2,
|
|
||||||
const DOMPointInit& aP3,
|
|
||||||
const DOMPointInit& aP4,
|
|
||||||
ErrorResult& aRV);
|
|
||||||
static already_AddRefed<DOMQuad>
|
|
||||||
Constructor(const GlobalObject& aGlobal, const DOMRectReadOnly& aRect,
|
|
||||||
ErrorResult& aRV);
|
|
||||||
|
|
||||||
DOMRectReadOnly* Bounds() const;
|
|
||||||
DOMPoint* P1() const { return mPoints[0]; }
|
|
||||||
DOMPoint* P2() const { return mPoints[1]; }
|
|
||||||
DOMPoint* P3() const { return mPoints[2]; }
|
|
||||||
DOMPoint* P4() const { return mPoints[3]; }
|
|
||||||
|
|
||||||
DOMPoint* Point(uint32_t aIndex) { return mPoints[aIndex]; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
class QuadBounds;
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> mParent;
|
|
||||||
nsRefPtr<DOMPoint> mPoints[4];
|
|
||||||
mutable nsRefPtr<QuadBounds> mBounds; // allocated lazily
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /*MOZILLA_DOMRECT_H_*/
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "mozilla/dom/DOMRect.h"
|
#include "DOMRect.h"
|
||||||
|
|
||||||
#include "nsPresContext.h"
|
#include "nsPresContext.h"
|
||||||
#include "mozilla/dom/DOMRectListBinding.h"
|
#include "mozilla/dom/DOMRectListBinding.h"
|
||||||
@@ -12,30 +12,20 @@
|
|||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(DOMRectReadOnly, mParent)
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(DOMRect, mParent)
|
||||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMRectReadOnly)
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMRect)
|
||||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMRectReadOnly)
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMRect)
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMRectReadOnly)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMRect)
|
||||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIDOMClientRect)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
JSObject*
|
|
||||||
DOMRectReadOnly::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mParent);
|
|
||||||
return DOMRectReadOnlyBinding::Wrap(aCx, aScope, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED1(DOMRect, DOMRectReadOnly, nsIDOMClientRect)
|
|
||||||
|
|
||||||
#define FORWARD_GETTER(_name) \
|
#define FORWARD_GETTER(_name) \
|
||||||
NS_IMETHODIMP \
|
NS_IMETHODIMP \
|
||||||
DOMRect::Get ## _name(float* aResult) \
|
DOMRect::Get ## _name(float* aResult) \
|
||||||
{ \
|
{ \
|
||||||
*aResult = float(_name()); \
|
*aResult = _name(); \
|
||||||
return NS_OK; \
|
return NS_OK; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,23 +43,6 @@ DOMRect::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
|
|||||||
return DOMRectBinding::Wrap(aCx, aScope, this);
|
return DOMRectBinding::Wrap(aCx, aScope, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<DOMRect>
|
|
||||||
DOMRect::Constructor(const GlobalObject& aGlobal, ErrorResult& aRV)
|
|
||||||
{
|
|
||||||
nsRefPtr<DOMRect> obj =
|
|
||||||
new DOMRect(aGlobal.GetAsSupports(), 0.0, 0.0, 0.0, 0.0);
|
|
||||||
return obj.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<DOMRect>
|
|
||||||
DOMRect::Constructor(const GlobalObject& aGlobal, double aX, double aY,
|
|
||||||
double aWidth, double aHeight, ErrorResult& aRV)
|
|
||||||
{
|
|
||||||
nsRefPtr<DOMRect> obj =
|
|
||||||
new DOMRect(aGlobal.GetAsSupports(), aX, aY, aWidth, aHeight);
|
|
||||||
return obj.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(DOMRectList, mParent, mArray)
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(DOMRectList, mParent, mArray)
|
||||||
|
|||||||
@@ -14,29 +14,33 @@
|
|||||||
#include "nsWrapperCache.h"
|
#include "nsWrapperCache.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/dom/BindingDeclarations.h"
|
|
||||||
#include "mozilla/ErrorResult.h"
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
struct nsRect;
|
struct nsRect;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
class DOMRectReadOnly : public nsISupports
|
class DOMRect MOZ_FINAL : public nsIDOMClientRect
|
||||||
, public nsWrapperCache
|
, public nsWrapperCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
DOMRect(nsISupports* aParent)
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMRectReadOnly)
|
: mParent(aParent), mX(0.0), mY(0.0), mWidth(0.0), mHeight(0.0)
|
||||||
|
|
||||||
virtual ~DOMRectReadOnly() {}
|
|
||||||
|
|
||||||
DOMRectReadOnly(nsISupports* aParent)
|
|
||||||
: mParent(aParent)
|
|
||||||
{
|
{
|
||||||
SetIsDOMBinding();
|
SetIsDOMBinding();
|
||||||
}
|
}
|
||||||
|
virtual ~DOMRect() {}
|
||||||
|
|
||||||
|
void SetRect(float aX, float aY, float aWidth, float aHeight) {
|
||||||
|
mX = aX; mY = aY; mWidth = aWidth; mHeight = aHeight;
|
||||||
|
}
|
||||||
|
void SetLayoutRect(const nsRect& aLayoutRect);
|
||||||
|
|
||||||
|
|
||||||
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMRect)
|
||||||
|
NS_DECL_NSIDOMCLIENTRECT
|
||||||
|
|
||||||
|
|
||||||
nsISupports* GetParentObject() const
|
nsISupports* GetParentObject() const
|
||||||
{
|
{
|
||||||
@@ -46,103 +50,40 @@ public:
|
|||||||
virtual JSObject* WrapObject(JSContext* aCx,
|
virtual JSObject* WrapObject(JSContext* aCx,
|
||||||
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual double X() const = 0;
|
|
||||||
virtual double Y() const = 0;
|
|
||||||
virtual double Width() const = 0;
|
|
||||||
virtual double Height() const = 0;
|
|
||||||
|
|
||||||
double Left() const
|
float Left() const
|
||||||
{
|
|
||||||
double x = X(), w = Width();
|
|
||||||
return std::min(x, x + w);
|
|
||||||
}
|
|
||||||
double Top() const
|
|
||||||
{
|
|
||||||
double y = Y(), h = Height();
|
|
||||||
return std::min(y, y + h);
|
|
||||||
}
|
|
||||||
double Right() const
|
|
||||||
{
|
|
||||||
double x = X(), w = Width();
|
|
||||||
return std::max(x, x + w);
|
|
||||||
}
|
|
||||||
double Bottom() const
|
|
||||||
{
|
|
||||||
double y = Y(), h = Height();
|
|
||||||
return std::max(y, y + h);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
nsCOMPtr<nsISupports> mParent;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DOMRect MOZ_FINAL : public DOMRectReadOnly
|
|
||||||
, public nsIDOMClientRect
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DOMRect(nsISupports* aParent, double aX = 0, double aY = 0,
|
|
||||||
double aWidth = 0, double aHeight = 0)
|
|
||||||
: DOMRectReadOnly(aParent)
|
|
||||||
, mX(aX)
|
|
||||||
, mY(aY)
|
|
||||||
, mWidth(aWidth)
|
|
||||||
, mHeight(aHeight)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
|
||||||
NS_DECL_NSIDOMCLIENTRECT
|
|
||||||
|
|
||||||
static already_AddRefed<DOMRect>
|
|
||||||
Constructor(const GlobalObject& aGlobal, ErrorResult& aRV);
|
|
||||||
static already_AddRefed<DOMRect>
|
|
||||||
Constructor(const GlobalObject& aGlobal, double aX, double aY,
|
|
||||||
double aWidth, double aHeight, ErrorResult& aRV);
|
|
||||||
|
|
||||||
virtual JSObject* WrapObject(JSContext* aCx,
|
|
||||||
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
void SetRect(float aX, float aY, float aWidth, float aHeight) {
|
|
||||||
mX = aX; mY = aY; mWidth = aWidth; mHeight = aHeight;
|
|
||||||
}
|
|
||||||
void SetLayoutRect(const nsRect& aLayoutRect);
|
|
||||||
|
|
||||||
virtual double X() const MOZ_OVERRIDE
|
|
||||||
{
|
{
|
||||||
return mX;
|
return mX;
|
||||||
}
|
}
|
||||||
virtual double Y() const MOZ_OVERRIDE
|
|
||||||
|
float Top() const
|
||||||
{
|
{
|
||||||
return mY;
|
return mY;
|
||||||
}
|
}
|
||||||
virtual double Width() const MOZ_OVERRIDE
|
|
||||||
|
float Right() const
|
||||||
|
{
|
||||||
|
return mX + mWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Bottom() const
|
||||||
|
{
|
||||||
|
return mY + mHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Width() const
|
||||||
{
|
{
|
||||||
return mWidth;
|
return mWidth;
|
||||||
}
|
}
|
||||||
virtual double Height() const MOZ_OVERRIDE
|
|
||||||
|
float Height() const
|
||||||
{
|
{
|
||||||
return mHeight;
|
return mHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetX(double aX)
|
|
||||||
{
|
|
||||||
mX = aX;
|
|
||||||
}
|
|
||||||
void SetY(double aY)
|
|
||||||
{
|
|
||||||
mY = aY;
|
|
||||||
}
|
|
||||||
void SetWidth(double aWidth)
|
|
||||||
{
|
|
||||||
mWidth = aWidth;
|
|
||||||
}
|
|
||||||
void SetHeight(double aHeight)
|
|
||||||
{
|
|
||||||
mHeight = aHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double mX, mY, mWidth, mHeight;
|
nsCOMPtr<nsISupports> mParent;
|
||||||
|
float mX, mY, mWidth, mHeight;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DOMRectList MOZ_FINAL : public nsIDOMClientRectList,
|
class DOMRectList MOZ_FINAL : public nsIDOMClientRectList,
|
||||||
@@ -204,7 +145,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsTArray<nsRefPtr<DOMRect> > mArray;
|
virtual ~DOMRectList() {}
|
||||||
|
|
||||||
|
nsTArray< nsRefPtr<DOMRect> > mArray;
|
||||||
nsCOMPtr<nsISupports> mParent;
|
nsCOMPtr<nsISupports> mParent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -60,8 +60,6 @@ EXPORTS.mozilla.dom += [
|
|||||||
'DocumentType.h',
|
'DocumentType.h',
|
||||||
'DOMImplementation.h',
|
'DOMImplementation.h',
|
||||||
'DOMParser.h',
|
'DOMParser.h',
|
||||||
'DOMPoint.h',
|
|
||||||
'DOMQuad.h',
|
|
||||||
'DOMRect.h',
|
'DOMRect.h',
|
||||||
'DOMStringList.h',
|
'DOMStringList.h',
|
||||||
'EventSource.h',
|
'EventSource.h',
|
||||||
@@ -81,8 +79,6 @@ UNIFIED_SOURCES += [
|
|||||||
'DocumentType.cpp',
|
'DocumentType.cpp',
|
||||||
'DOMImplementation.cpp',
|
'DOMImplementation.cpp',
|
||||||
'DOMParser.cpp',
|
'DOMParser.cpp',
|
||||||
'DOMPoint.cpp',
|
|
||||||
'DOMQuad.cpp',
|
|
||||||
'DOMRect.cpp',
|
'DOMRect.cpp',
|
||||||
'DOMStringList.cpp',
|
'DOMStringList.cpp',
|
||||||
'Element.cpp',
|
'Element.cpp',
|
||||||
|
|||||||
@@ -103,7 +103,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
#include "nsDOMMutationObserver.h"
|
#include "nsDOMMutationObserver.h"
|
||||||
#include "GeometryUtils.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
@@ -1141,14 +1140,6 @@ nsINode::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
|||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsINode::GetBoxQuads(const BoxQuadOptions& aOptions,
|
|
||||||
nsTArray<nsRefPtr<DOMQuad> >& aResult,
|
|
||||||
mozilla::ErrorResult& aRv)
|
|
||||||
{
|
|
||||||
mozilla::GetBoxQuads(this, aOptions, aResult, aRv);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsINode::DispatchEvent(nsIDOMEvent *aEvent, bool* aRetVal)
|
nsINode::DispatchEvent(nsIDOMEvent *aEvent, bool* aRetVal)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
|
|
||||||
#ifdef LoadImage
|
#if defined(XP_WIN)
|
||||||
// Undefine LoadImage to prevent naming conflict with Windows.
|
// Undefine LoadImage to prevent naming conflict with Windows.
|
||||||
#undef LoadImage
|
#undef LoadImage
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -31,11 +31,6 @@ class nsPresContext;
|
|||||||
class nsIContent;
|
class nsIContent;
|
||||||
class imgRequestProxy;
|
class imgRequestProxy;
|
||||||
|
|
||||||
#ifdef LoadImage
|
|
||||||
// Undefine LoadImage to prevent naming conflict with Windows.
|
|
||||||
#undef LoadImage
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class nsImageLoadingContent : public nsIImageLoadingContent,
|
class nsImageLoadingContent : public nsIImageLoadingContent,
|
||||||
public imgIOnloadBlocker
|
public imgIOnloadBlocker
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -220,6 +220,11 @@ DOMInterfaces = {
|
|||||||
'nativeType': 'mozilla::dom::workers::ChromeWorkerPrivate',
|
'nativeType': 'mozilla::dom::workers::ChromeWorkerPrivate',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'DOMRectList': {
|
||||||
|
'headerFile': 'mozilla/dom/DOMRect.h',
|
||||||
|
'resultNotAddRefed': [ 'item' ]
|
||||||
|
},
|
||||||
|
|
||||||
'Console': {
|
'Console': {
|
||||||
'implicitJSContext': [ 'trace', 'time', 'timeEnd' ],
|
'implicitJSContext': [ 'trace', 'time', 'timeEnd' ],
|
||||||
},
|
},
|
||||||
@@ -328,24 +333,6 @@ DOMInterfaces = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
'DOMPointReadOnly': {
|
|
||||||
'headerFile': 'mozilla/dom/DOMPoint.h',
|
|
||||||
'concrete': False,
|
|
||||||
},
|
|
||||||
|
|
||||||
'DOMRectList': {
|
|
||||||
'headerFile': 'mozilla/dom/DOMRect.h',
|
|
||||||
'resultNotAddRefed': [ 'item' ]
|
|
||||||
},
|
|
||||||
|
|
||||||
'DOMRectReadOnly': {
|
|
||||||
'headerFile': 'mozilla/dom/DOMRect.h',
|
|
||||||
},
|
|
||||||
|
|
||||||
'DOMQuad': {
|
|
||||||
'resultNotAddRefed': [ 'bounds', 'p0', 'p1', 'p2', 'p3' ]
|
|
||||||
},
|
|
||||||
|
|
||||||
'DOMSettableTokenList': {
|
'DOMSettableTokenList': {
|
||||||
'nativeType': 'nsDOMSettableTokenList',
|
'nativeType': 'nsDOMSettableTokenList',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -305,18 +305,10 @@ var interfaceNamesInGlobalScope =
|
|||||||
"DOMMMIError",
|
"DOMMMIError",
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
"DOMParser",
|
"DOMParser",
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
|
||||||
"DOMPoint",
|
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
|
||||||
"DOMPointReadOnly",
|
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
|
||||||
"DOMQuad",
|
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
"DOMRect",
|
"DOMRect",
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
"DOMRectList",
|
"DOMRectList",
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
|
||||||
"DOMRectReadOnly",
|
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
"DOMRequest",
|
"DOMRequest",
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*
|
|
||||||
* The origin of this IDL file is
|
|
||||||
* http://dev.w3.org/fxtf/geometry/
|
|
||||||
*
|
|
||||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
|
||||||
* liability, trademark and document use rules apply.
|
|
||||||
*/
|
|
||||||
|
|
||||||
[Pref="layout.css.DOMPoint.enabled"]
|
|
||||||
interface DOMPointReadOnly {
|
|
||||||
readonly attribute unrestricted double x;
|
|
||||||
readonly attribute unrestricted double y;
|
|
||||||
readonly attribute unrestricted double z;
|
|
||||||
readonly attribute unrestricted double w;
|
|
||||||
};
|
|
||||||
|
|
||||||
[Pref="layout.css.DOMPoint.enabled",
|
|
||||||
Constructor(optional DOMPointInit point),
|
|
||||||
Constructor(unrestricted double x, unrestricted double y,
|
|
||||||
optional unrestricted double z = 0, optional unrestricted double w = 1)]
|
|
||||||
interface DOMPoint : DOMPointReadOnly {
|
|
||||||
inherit attribute unrestricted double x;
|
|
||||||
inherit attribute unrestricted double y;
|
|
||||||
inherit attribute unrestricted double z;
|
|
||||||
inherit attribute unrestricted double w;
|
|
||||||
};
|
|
||||||
|
|
||||||
dictionary DOMPointInit {
|
|
||||||
unrestricted double x = 0;
|
|
||||||
unrestricted double y = 0;
|
|
||||||
unrestricted double z = 0;
|
|
||||||
unrestricted double w = 1;
|
|
||||||
};
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*
|
|
||||||
* The origin of this IDL file is
|
|
||||||
* http://dev.w3.org/fxtf/geometry/
|
|
||||||
*
|
|
||||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
|
||||||
* liability, trademark and document use rules apply.
|
|
||||||
*/
|
|
||||||
|
|
||||||
[Pref="layout.css.DOMQuad.enabled",
|
|
||||||
Constructor(optional DOMPointInit p1, optional DOMPointInit p2,
|
|
||||||
optional DOMPointInit p3, optional DOMPointInit p4),
|
|
||||||
Constructor(DOMRectReadOnly rect)]
|
|
||||||
interface DOMQuad {
|
|
||||||
[SameObject] readonly attribute DOMPoint p1;
|
|
||||||
[SameObject] readonly attribute DOMPoint p2;
|
|
||||||
[SameObject] readonly attribute DOMPoint p3;
|
|
||||||
[SameObject] readonly attribute DOMPoint p4;
|
|
||||||
[SameObject] readonly attribute DOMRectReadOnly bounds;
|
|
||||||
};
|
|
||||||
@@ -1,32 +1,14 @@
|
|||||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
*
|
|
||||||
* The origin of this IDL file is
|
|
||||||
* http://dev.w3.org/fxtf/geometry/
|
|
||||||
*
|
|
||||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
|
||||||
* liability, trademark and document use rules apply.
|
|
||||||
*/
|
|
||||||
|
|
||||||
[Constructor,
|
interface DOMRect
|
||||||
Constructor(unrestricted double x, unrestricted double y,
|
{
|
||||||
unrestricted double width, unrestricted double height)]
|
readonly attribute float left;
|
||||||
interface DOMRect : DOMRectReadOnly {
|
readonly attribute float top;
|
||||||
inherit attribute unrestricted double x;
|
readonly attribute float right;
|
||||||
inherit attribute unrestricted double y;
|
readonly attribute float bottom;
|
||||||
inherit attribute unrestricted double width;
|
readonly attribute float width;
|
||||||
inherit attribute unrestricted double height;
|
readonly attribute float height;
|
||||||
};
|
|
||||||
|
|
||||||
interface DOMRectReadOnly {
|
|
||||||
readonly attribute unrestricted double x;
|
|
||||||
readonly attribute unrestricted double y;
|
|
||||||
readonly attribute unrestricted double width;
|
|
||||||
readonly attribute unrestricted double height;
|
|
||||||
readonly attribute unrestricted double top;
|
|
||||||
readonly attribute unrestricted double right;
|
|
||||||
readonly attribute unrestricted double bottom;
|
|
||||||
readonly attribute unrestricted double left;
|
|
||||||
};
|
};
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*
|
|
||||||
* The origin of this IDL file is
|
|
||||||
* http://dev.w3.org/csswg/cssom-view/
|
|
||||||
*
|
|
||||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
|
||||||
* liability, trademark and document use rules apply.
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum CSSBoxType { "margin", "border", "padding", "content" };
|
|
||||||
dictionary BoxQuadOptions {
|
|
||||||
CSSBoxType box = "border";
|
|
||||||
GeometryNode relativeTo;
|
|
||||||
};
|
|
||||||
|
|
||||||
dictionary ConvertCoordinateOptions {
|
|
||||||
CSSBoxType fromBox = "border";
|
|
||||||
CSSBoxType toBox = "border";
|
|
||||||
};
|
|
||||||
|
|
||||||
[NoInterfaceObject]
|
|
||||||
interface GeometryUtils {
|
|
||||||
[Throws, Pref="layout.css.getBoxQuads.enabled"]
|
|
||||||
sequence<DOMQuad> getBoxQuads(optional BoxQuadOptions options);
|
|
||||||
// DOMQuad convertQuadFromNode(DOMQuad quad, GeometryNode from, optional ConvertCoordinateOptions options);
|
|
||||||
// DOMQuad convertRectFromNode(DOMRectReadOnly rect, GeometryNode from, optional ConvertCoordinateOptions options);
|
|
||||||
// DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from, optional ConvertCoordinateOptions options);
|
|
||||||
};
|
|
||||||
|
|
||||||
Text implements GeometryUtils;
|
|
||||||
Element implements GeometryUtils;
|
|
||||||
// PseudoElement implements GeometryUtils;
|
|
||||||
Document implements GeometryUtils;
|
|
||||||
|
|
||||||
typedef (Text or Element /* or PseudoElement */ or Document) GeometryNode;
|
|
||||||
@@ -24,6 +24,8 @@ CSSStyleDeclaration implements LegacyQueryInterface;
|
|||||||
CSSValueList implements LegacyQueryInterface;
|
CSSValueList implements LegacyQueryInterface;
|
||||||
DOMImplementation implements LegacyQueryInterface;
|
DOMImplementation implements LegacyQueryInterface;
|
||||||
DOMParser implements LegacyQueryInterface;
|
DOMParser implements LegacyQueryInterface;
|
||||||
|
DOMRect implements LegacyQueryInterface;
|
||||||
|
DOMRectList implements LegacyQueryInterface;
|
||||||
DOMStringMap implements LegacyQueryInterface;
|
DOMStringMap implements LegacyQueryInterface;
|
||||||
DOMTokenList implements LegacyQueryInterface;
|
DOMTokenList implements LegacyQueryInterface;
|
||||||
Document implements LegacyQueryInterface;
|
Document implements LegacyQueryInterface;
|
||||||
|
|||||||
@@ -83,8 +83,6 @@ WEBIDL_FILES = [
|
|||||||
'DOMImplementation.webidl',
|
'DOMImplementation.webidl',
|
||||||
'DOMMMIError.webidl',
|
'DOMMMIError.webidl',
|
||||||
'DOMParser.webidl',
|
'DOMParser.webidl',
|
||||||
'DOMPoint.webidl',
|
|
||||||
'DOMQuad.webidl',
|
|
||||||
'DOMRect.webidl',
|
'DOMRect.webidl',
|
||||||
'DOMRectList.webidl',
|
'DOMRectList.webidl',
|
||||||
'DOMRequest.webidl',
|
'DOMRequest.webidl',
|
||||||
@@ -115,7 +113,6 @@ WEBIDL_FILES = [
|
|||||||
'Function.webidl',
|
'Function.webidl',
|
||||||
'GainNode.webidl',
|
'GainNode.webidl',
|
||||||
'Geolocation.webidl',
|
'Geolocation.webidl',
|
||||||
'GeometryUtils.webidl',
|
|
||||||
'GetUserMediaRequest.webidl',
|
'GetUserMediaRequest.webidl',
|
||||||
'History.webidl',
|
'History.webidl',
|
||||||
'HTMLAnchorElement.webidl',
|
'HTMLAnchorElement.webidl',
|
||||||
|
|||||||
@@ -1,238 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "GeometryUtils.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/GeometryUtilsBinding.h"
|
|
||||||
#include "mozilla/dom/Element.h"
|
|
||||||
#include "mozilla/dom/Text.h"
|
|
||||||
#include "mozilla/dom/DOMQuad.h"
|
|
||||||
#include "nsIFrame.h"
|
|
||||||
#include "nsGenericDOMDataNode.h"
|
|
||||||
#include "nsCSSFrameConstructor.h"
|
|
||||||
#include "nsLayoutUtils.h"
|
|
||||||
#include "nsSVGUtils.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
|
||||||
using namespace mozilla::dom;
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
|
|
||||||
typedef OwningTextOrElementOrDocument GeometryNode;
|
|
||||||
|
|
||||||
enum GeometryNodeType {
|
|
||||||
GEOMETRY_NODE_ELEMENT,
|
|
||||||
GEOMETRY_NODE_TEXT,
|
|
||||||
GEOMETRY_NODE_DOCUMENT
|
|
||||||
};
|
|
||||||
|
|
||||||
static nsIFrame*
|
|
||||||
GetFrameForNode(nsINode* aNode, GeometryNodeType aType)
|
|
||||||
{
|
|
||||||
nsIDocument* doc = aNode->OwnerDoc();
|
|
||||||
doc->FlushPendingNotifications(Flush_Layout);
|
|
||||||
switch (aType) {
|
|
||||||
case GEOMETRY_NODE_ELEMENT:
|
|
||||||
return aNode->AsContent()->GetPrimaryFrame();
|
|
||||||
case GEOMETRY_NODE_TEXT: {
|
|
||||||
nsIPresShell* presShell = doc->GetShell();
|
|
||||||
if (presShell) {
|
|
||||||
return presShell->FrameConstructor()->EnsureFrameForTextNode(
|
|
||||||
static_cast<nsGenericDOMDataNode*>(aNode));
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
case GEOMETRY_NODE_DOCUMENT: {
|
|
||||||
nsIPresShell* presShell = doc->GetShell();
|
|
||||||
return presShell ? presShell->GetRootFrame() : nullptr;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
MOZ_ASSERT(false, "Unknown GeometryNodeType");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static nsIFrame*
|
|
||||||
GetFrameForGeometryNode(const Optional<GeometryNode>& aGeometryNode,
|
|
||||||
nsINode* aDefaultNode)
|
|
||||||
{
|
|
||||||
if (!aGeometryNode.WasPassed()) {
|
|
||||||
return GetFrameForNode(aDefaultNode->OwnerDoc(), GEOMETRY_NODE_DOCUMENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
const GeometryNode& value = aGeometryNode.Value();
|
|
||||||
if (value.IsElement()) {
|
|
||||||
return GetFrameForNode(value.GetAsElement(), GEOMETRY_NODE_ELEMENT);
|
|
||||||
}
|
|
||||||
if (value.IsDocument()) {
|
|
||||||
return GetFrameForNode(value.GetAsDocument(), GEOMETRY_NODE_DOCUMENT);
|
|
||||||
}
|
|
||||||
return GetFrameForNode(value.GetAsText(), GEOMETRY_NODE_TEXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static nsIFrame*
|
|
||||||
GetFrameForNode(nsINode* aNode)
|
|
||||||
{
|
|
||||||
if (aNode->IsElement()) {
|
|
||||||
return GetFrameForNode(aNode, GEOMETRY_NODE_ELEMENT);
|
|
||||||
}
|
|
||||||
if (aNode == aNode->OwnerDoc()) {
|
|
||||||
return GetFrameForNode(aNode, GEOMETRY_NODE_DOCUMENT);
|
|
||||||
}
|
|
||||||
NS_ASSERTION(aNode->IsNodeOfType(nsINode::eTEXT), "Unknown node type");
|
|
||||||
return GetFrameForNode(aNode, GEOMETRY_NODE_TEXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static nsIFrame*
|
|
||||||
GetFirstNonAnonymousFrameForGeometryNode(const Optional<GeometryNode>& aNode,
|
|
||||||
nsINode* aDefaultNode)
|
|
||||||
{
|
|
||||||
nsIFrame* f = GetFrameForGeometryNode(aNode, aDefaultNode);
|
|
||||||
if (f) {
|
|
||||||
f = nsLayoutUtils::GetFirstNonAnonymousFrame(f);
|
|
||||||
}
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This can modify aFrame to point to a different frame. This is needed to
|
|
||||||
* handle SVG, where SVG elements can only compute a rect that's valid with
|
|
||||||
* respect to the "outer SVG" frame.
|
|
||||||
*/
|
|
||||||
static nsRect
|
|
||||||
GetBoxRectForFrame(nsIFrame** aFrame, CSSBoxType aType)
|
|
||||||
{
|
|
||||||
nsRect r;
|
|
||||||
nsIFrame* f = nsSVGUtils::GetOuterSVGFrameAndCoveredRegion(*aFrame, &r);
|
|
||||||
if (f) {
|
|
||||||
// For SVG, the BoxType is ignored.
|
|
||||||
*aFrame = f;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
f = *aFrame;
|
|
||||||
switch (aType) {
|
|
||||||
case CSSBoxType::Content: r = f->GetContentRectRelativeToSelf(); break;
|
|
||||||
case CSSBoxType::Padding: r = f->GetPaddingRectRelativeToSelf(); break;
|
|
||||||
case CSSBoxType::Border: r = nsRect(nsPoint(0, 0), f->GetSize()); break;
|
|
||||||
case CSSBoxType::Margin: {
|
|
||||||
r = nsRect(nsPoint(0, 0), f->GetSize());
|
|
||||||
r.Inflate(f->GetUsedMargin());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: MOZ_ASSERT(false, "unknown box type"); return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
class AccumulateQuadCallback : public nsLayoutUtils::BoxCallback {
|
|
||||||
public:
|
|
||||||
AccumulateQuadCallback(nsISupports* aParentObject,
|
|
||||||
nsTArray<nsRefPtr<DOMQuad> >& aResult,
|
|
||||||
nsIFrame* aRelativeToFrame,
|
|
||||||
const nsPoint& aRelativeToBoxTopLeft,
|
|
||||||
CSSBoxType aBoxType)
|
|
||||||
: mParentObject(aParentObject)
|
|
||||||
, mResult(aResult)
|
|
||||||
, mRelativeToFrame(aRelativeToFrame)
|
|
||||||
, mRelativeToBoxTopLeft(aRelativeToBoxTopLeft)
|
|
||||||
, mBoxType(aBoxType)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void AddBox(nsIFrame* aFrame) MOZ_OVERRIDE
|
|
||||||
{
|
|
||||||
nsIFrame* f = aFrame;
|
|
||||||
nsRect box = GetBoxRectForFrame(&f, mBoxType);
|
|
||||||
nsPoint appUnits[4] =
|
|
||||||
{ box.TopLeft(), box.TopRight(), box.BottomRight(), box.BottomLeft() };
|
|
||||||
CSSPoint points[4];
|
|
||||||
for (uint32_t i = 0; i < 4; ++i) {
|
|
||||||
points[i] = CSSPoint(nsPresContext::AppUnitsToFloatCSSPixels(appUnits[i].x),
|
|
||||||
nsPresContext::AppUnitsToFloatCSSPixels(appUnits[i].y));
|
|
||||||
}
|
|
||||||
nsLayoutUtils::TransformResult rv =
|
|
||||||
nsLayoutUtils::TransformPoints(f, mRelativeToFrame, 4, points);
|
|
||||||
if (rv == nsLayoutUtils::TRANSFORM_SUCCEEDED) {
|
|
||||||
CSSPoint delta(nsPresContext::AppUnitsToFloatCSSPixels(mRelativeToBoxTopLeft.x),
|
|
||||||
nsPresContext::AppUnitsToFloatCSSPixels(mRelativeToBoxTopLeft.y));
|
|
||||||
for (uint32_t i = 0; i < 4; ++i) {
|
|
||||||
points[i] -= delta;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PodArrayZero(points);
|
|
||||||
}
|
|
||||||
mResult.AppendElement(new DOMQuad(mParentObject, points));
|
|
||||||
}
|
|
||||||
|
|
||||||
nsISupports* mParentObject;
|
|
||||||
nsTArray<nsRefPtr<DOMQuad> >& mResult;
|
|
||||||
nsIFrame* mRelativeToFrame;
|
|
||||||
nsPoint mRelativeToBoxTopLeft;
|
|
||||||
CSSBoxType mBoxType;
|
|
||||||
};
|
|
||||||
|
|
||||||
static nsPresContext*
|
|
||||||
FindTopLevelPresContext(nsPresContext* aPC)
|
|
||||||
{
|
|
||||||
bool isChrome = aPC->IsChrome();
|
|
||||||
nsPresContext* pc = aPC;
|
|
||||||
for (;;) {
|
|
||||||
nsPresContext* parent = pc->GetParentPresContext();
|
|
||||||
if (!parent || parent->IsChrome() != isChrome) {
|
|
||||||
return pc;
|
|
||||||
}
|
|
||||||
pc = parent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
CheckFramesInSameTopLevelBrowsingContext(nsIFrame* aFrame1, nsIFrame* aFrame2)
|
|
||||||
{
|
|
||||||
nsPresContext* pc1 = aFrame1->PresContext();
|
|
||||||
nsPresContext* pc2 = aFrame2->PresContext();
|
|
||||||
if (pc1 == pc2) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (nsContentUtils::IsCallerChrome()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (FindTopLevelPresContext(pc1) == FindTopLevelPresContext(pc2)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetBoxQuads(nsINode* aNode,
|
|
||||||
const dom::BoxQuadOptions& aOptions,
|
|
||||||
nsTArray<nsRefPtr<DOMQuad> >& aResult,
|
|
||||||
ErrorResult& aRv)
|
|
||||||
{
|
|
||||||
nsIFrame* frame = GetFrameForNode(aNode);
|
|
||||||
if (!frame) {
|
|
||||||
// No boxes to return
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
nsIDocument* ownerDoc = aNode->OwnerDoc();
|
|
||||||
nsIFrame* relativeToFrame =
|
|
||||||
GetFirstNonAnonymousFrameForGeometryNode(aOptions.mRelativeTo, ownerDoc);
|
|
||||||
if (!relativeToFrame) {
|
|
||||||
aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!CheckFramesInSameTopLevelBrowsingContext(frame, relativeToFrame)) {
|
|
||||||
aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// GetBoxRectForFrame can modify relativeToFrame so call it first.
|
|
||||||
nsPoint relativeToTopLeft =
|
|
||||||
GetBoxRectForFrame(&relativeToFrame, CSSBoxType::Border).TopLeft();
|
|
||||||
AccumulateQuadCallback callback(ownerDoc, aResult, relativeToFrame,
|
|
||||||
relativeToTopLeft, aOptions.mBox);
|
|
||||||
nsLayoutUtils::GetAllInFlowBoxes(frame, &callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef MOZILLA_GEOMETRYUTILS_H_
|
|
||||||
#define MOZILLA_GEOMETRYUTILS_H_
|
|
||||||
|
|
||||||
#include "mozilla/ErrorResult.h"
|
|
||||||
#include "nsTArray.h"
|
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This file defines utility functions for converting between layout
|
|
||||||
* coordinate systems.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class nsINode;
|
|
||||||
class nsIDocument;
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
|
|
||||||
namespace dom {
|
|
||||||
struct BoxQuadOptions;
|
|
||||||
class DOMQuad;
|
|
||||||
class Element;
|
|
||||||
class Text;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes quads for aNode using aOptions, according to GeometryUtils.getBoxQuads.
|
|
||||||
* May set an error in aRv.
|
|
||||||
*/
|
|
||||||
void GetBoxQuads(nsINode* aNode,
|
|
||||||
const dom::BoxQuadOptions& aOptions,
|
|
||||||
nsTArray<nsRefPtr<dom::DOMQuad> >& aResult,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* MOZILLA_GEOMETRYUTILS_H_ */
|
|
||||||
@@ -60,7 +60,6 @@ EXPORTS += [
|
|||||||
]
|
]
|
||||||
|
|
||||||
EXPORTS.mozilla += [
|
EXPORTS.mozilla += [
|
||||||
'GeometryUtils.h',
|
|
||||||
'PaintTracker.h',
|
'PaintTracker.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -70,7 +69,6 @@ UNIFIED_SOURCES += [
|
|||||||
'DisplayListClipState.cpp',
|
'DisplayListClipState.cpp',
|
||||||
'FrameLayerBuilder.cpp',
|
'FrameLayerBuilder.cpp',
|
||||||
'FramePropertyTable.cpp',
|
'FramePropertyTable.cpp',
|
||||||
'GeometryUtils.cpp',
|
|
||||||
'MaskLayerImageCache.cpp',
|
'MaskLayerImageCache.cpp',
|
||||||
'nsCaret.cpp',
|
'nsCaret.cpp',
|
||||||
'nsCounterManager.cpp',
|
'nsCounterManager.cpp',
|
||||||
|
|||||||
@@ -1893,66 +1893,6 @@ nsLayoutUtils::GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncesto
|
|||||||
return ctm;
|
return ctm;
|
||||||
}
|
}
|
||||||
|
|
||||||
static nsIFrame*
|
|
||||||
FindNearestCommonAncestorFrame(nsIFrame* aFrame1, nsIFrame* aFrame2)
|
|
||||||
{
|
|
||||||
nsAutoTArray<nsIFrame*,100> ancestors1;
|
|
||||||
nsAutoTArray<nsIFrame*,100> ancestors2;
|
|
||||||
nsIFrame* commonAncestor = nullptr;
|
|
||||||
if (aFrame1->PresContext() == aFrame2->PresContext()) {
|
|
||||||
commonAncestor = aFrame1->PresContext()->PresShell()->GetRootFrame();
|
|
||||||
}
|
|
||||||
for (nsIFrame* f = aFrame1; f != commonAncestor;
|
|
||||||
f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
|
|
||||||
ancestors1.AppendElement(f);
|
|
||||||
}
|
|
||||||
for (nsIFrame* f = aFrame2; f != commonAncestor;
|
|
||||||
f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
|
|
||||||
ancestors2.AppendElement(f);
|
|
||||||
}
|
|
||||||
uint32_t minLengths = std::min(ancestors1.Length(), ancestors2.Length());
|
|
||||||
for (uint32_t i = 1; i <= minLengths; ++i) {
|
|
||||||
if (ancestors1[ancestors1.Length() - i] == ancestors2[ancestors2.Length() - i]) {
|
|
||||||
commonAncestor = ancestors1[ancestors1.Length() - i];
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return commonAncestor;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsLayoutUtils::TransformResult
|
|
||||||
nsLayoutUtils::TransformPoints(nsIFrame* aFromFrame, nsIFrame* aToFrame,
|
|
||||||
uint32_t aPointCount, CSSPoint* aPoints)
|
|
||||||
{
|
|
||||||
nsIFrame* nearestCommonAncestor = FindNearestCommonAncestorFrame(aFromFrame, aToFrame);
|
|
||||||
if (!nearestCommonAncestor) {
|
|
||||||
return NO_COMMON_ANCESTOR;
|
|
||||||
}
|
|
||||||
gfx3DMatrix downToDest = GetTransformToAncestor(aToFrame, nearestCommonAncestor);
|
|
||||||
if (downToDest.IsSingular()) {
|
|
||||||
return NONINVERTIBLE_TRANSFORM;
|
|
||||||
}
|
|
||||||
downToDest.Invert();
|
|
||||||
gfx3DMatrix upToAncestor = GetTransformToAncestor(aFromFrame, nearestCommonAncestor);
|
|
||||||
CSSToLayoutDeviceScale devPixelsPerCSSPixelFromFrame(
|
|
||||||
double(nsPresContext::AppUnitsPerCSSPixel())/
|
|
||||||
aFromFrame->PresContext()->AppUnitsPerDevPixel());
|
|
||||||
CSSToLayoutDeviceScale devPixelsPerCSSPixelToFrame(
|
|
||||||
double(nsPresContext::AppUnitsPerCSSPixel())/
|
|
||||||
aToFrame->PresContext()->AppUnitsPerDevPixel());
|
|
||||||
for (uint32_t i = 0; i < aPointCount; ++i) {
|
|
||||||
LayoutDevicePoint devPixels = aPoints[i] * devPixelsPerCSSPixelFromFrame;
|
|
||||||
gfxPoint toDevPixels = downToDest.ProjectPoint(
|
|
||||||
upToAncestor.ProjectPoint(gfxPoint(devPixels.x, devPixels.y)));
|
|
||||||
// Divide here so that when the devPixelsPerCSSPixels are the same, we get the correct
|
|
||||||
// answer instead of some inaccuracy multiplying a number by its reciprocal.
|
|
||||||
aPoints[i] = LayoutDevicePoint(toDevPixels.x, toDevPixels.y) /
|
|
||||||
devPixelsPerCSSPixelToFrame;
|
|
||||||
}
|
|
||||||
return TRANSFORM_SUCCEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame,
|
nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame,
|
||||||
gfx3DMatrix* aTransform)
|
gfx3DMatrix* aTransform)
|
||||||
@@ -2646,43 +2586,6 @@ nsLayoutUtils::GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame*
|
|
||||||
nsLayoutUtils::GetFirstNonAnonymousFrame(nsIFrame* aFrame)
|
|
||||||
{
|
|
||||||
while (aFrame) {
|
|
||||||
nsIAtom* pseudoType = aFrame->StyleContext()->GetPseudo();
|
|
||||||
|
|
||||||
if (pseudoType == nsCSSAnonBoxes::tableOuter) {
|
|
||||||
nsIFrame* f = GetFirstNonAnonymousFrame(aFrame->GetFirstPrincipalChild());
|
|
||||||
if (f) {
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
nsIFrame* kid = aFrame->GetFirstChild(nsIFrame::kCaptionList);
|
|
||||||
if (kid) {
|
|
||||||
f = GetFirstNonAnonymousFrame(kid);
|
|
||||||
if (f) {
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (pseudoType == nsCSSAnonBoxes::mozAnonymousBlock ||
|
|
||||||
pseudoType == nsCSSAnonBoxes::mozAnonymousPositionedBlock ||
|
|
||||||
pseudoType == nsCSSAnonBoxes::mozMathMLAnonymousBlock ||
|
|
||||||
pseudoType == nsCSSAnonBoxes::mozXULAnonymousBlock) {
|
|
||||||
for (nsIFrame* kid = aFrame->GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) {
|
|
||||||
nsIFrame* f = GetFirstNonAnonymousFrame(kid);
|
|
||||||
if (f) {
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return aFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
aFrame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(aFrame);
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct BoxToRect : public nsLayoutUtils::BoxCallback {
|
struct BoxToRect : public nsLayoutUtils::BoxCallback {
|
||||||
nsIFrame* mRelativeTo;
|
nsIFrame* mRelativeTo;
|
||||||
nsLayoutUtils::RectCallback* mCallback;
|
nsLayoutUtils::RectCallback* mCallback;
|
||||||
|
|||||||
@@ -6,29 +6,6 @@
|
|||||||
#ifndef nsLayoutUtils_h__
|
#ifndef nsLayoutUtils_h__
|
||||||
#define nsLayoutUtils_h__
|
#define nsLayoutUtils_h__
|
||||||
|
|
||||||
#include "mozilla/MemoryReporting.h"
|
|
||||||
#include "nsChangeHint.h"
|
|
||||||
#include "nsAutoPtr.h"
|
|
||||||
#include "nsFrameList.h"
|
|
||||||
#include "nsThreadUtils.h"
|
|
||||||
#include "nsIPrincipal.h"
|
|
||||||
#include "GraphicsFilter.h"
|
|
||||||
#include "nsCSSPseudoElements.h"
|
|
||||||
#include "FrameMetrics.h"
|
|
||||||
#include "gfx3DMatrix.h"
|
|
||||||
#include "nsIWidget.h"
|
|
||||||
#include "nsCSSProperty.h"
|
|
||||||
#include "nsStyleCoord.h"
|
|
||||||
#include "nsStyleConsts.h"
|
|
||||||
#include "nsGkAtoms.h"
|
|
||||||
#include "nsRuleNode.h"
|
|
||||||
#include "imgIContainer.h"
|
|
||||||
#include "mozilla/gfx/2D.h"
|
|
||||||
#include "Units.h"
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
class nsIFormControlFrame;
|
class nsIFormControlFrame;
|
||||||
class nsPresContext;
|
class nsPresContext;
|
||||||
class nsIContent;
|
class nsIContent;
|
||||||
@@ -53,11 +30,32 @@ class gfxContext;
|
|||||||
class nsPIDOMWindow;
|
class nsPIDOMWindow;
|
||||||
class imgIRequest;
|
class imgIRequest;
|
||||||
class nsIDocument;
|
class nsIDocument;
|
||||||
class gfxPoint;
|
|
||||||
struct nsStyleFont;
|
struct nsStyleFont;
|
||||||
struct nsStyleImageOrientation;
|
struct nsStyleImageOrientation;
|
||||||
struct nsOverflowAreas;
|
struct nsOverflowAreas;
|
||||||
|
|
||||||
|
#include "mozilla/MemoryReporting.h"
|
||||||
|
#include "nsChangeHint.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsFrameList.h"
|
||||||
|
#include "nsThreadUtils.h"
|
||||||
|
#include "nsIPrincipal.h"
|
||||||
|
#include "GraphicsFilter.h"
|
||||||
|
#include "nsCSSPseudoElements.h"
|
||||||
|
#include "FrameMetrics.h"
|
||||||
|
#include "gfx3DMatrix.h"
|
||||||
|
#include "nsIWidget.h"
|
||||||
|
#include "nsCSSProperty.h"
|
||||||
|
#include "nsStyleCoord.h"
|
||||||
|
#include "nsStyleConsts.h"
|
||||||
|
#include "nsGkAtoms.h"
|
||||||
|
#include "nsRuleNode.h"
|
||||||
|
#include "imgIContainer.h"
|
||||||
|
#include "mozilla/gfx/2D.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class SVGImageContext;
|
class SVGImageContext;
|
||||||
struct IntrinsicSize;
|
struct IntrinsicSize;
|
||||||
@@ -109,7 +107,6 @@ class nsLayoutUtils
|
|||||||
public:
|
public:
|
||||||
typedef mozilla::layers::FrameMetrics FrameMetrics;
|
typedef mozilla::layers::FrameMetrics FrameMetrics;
|
||||||
typedef FrameMetrics::ViewID ViewID;
|
typedef FrameMetrics::ViewID ViewID;
|
||||||
typedef mozilla::CSSPoint CSSPoint;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds previously assigned ViewID for the given content element, if any.
|
* Finds previously assigned ViewID for the given content element, if any.
|
||||||
@@ -686,24 +683,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
static gfx3DMatrix GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncestor);
|
static gfx3DMatrix GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncestor);
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms a list of CSSPoints from aFromFrame to aToFrame, taking into
|
|
||||||
* account all relevant transformations on the frames up to (but excluding)
|
|
||||||
* their nearest common ancestor.
|
|
||||||
* If we encounter a transform that we need to invert but which is
|
|
||||||
* non-invertible, we return NONINVERTIBLE_TRANSFORM. If the frames have
|
|
||||||
* no common ancestor, we return NO_COMMON_ANCESTOR.
|
|
||||||
* If this returns TRANSFORM_SUCCEEDED, the points in aPoints are transformed
|
|
||||||
* in-place, otherwise they are untouched.
|
|
||||||
*/
|
|
||||||
enum TransformResult {
|
|
||||||
TRANSFORM_SUCCEEDED,
|
|
||||||
NO_COMMON_ANCESTOR,
|
|
||||||
NONINVERTIBLE_TRANSFORM
|
|
||||||
};
|
|
||||||
static TransformResult TransformPoints(nsIFrame* aFromFrame, nsIFrame* aToFrame,
|
|
||||||
uint32_t aPointCount, CSSPoint* aPoints);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if a "layer transform" could be computed for aFrame,
|
* Return true if a "layer transform" could be computed for aFrame,
|
||||||
* and optionally return the computed transform. The returned
|
* and optionally return the computed transform. The returned
|
||||||
@@ -898,12 +877,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
static void GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback);
|
static void GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback);
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the first frame descendant of aFrame (including aFrame) which is
|
|
||||||
* not an anonymous frame that getBoxQuads/getClientRects should ignore.
|
|
||||||
*/
|
|
||||||
static nsIFrame* GetFirstNonAnonymousFrame(nsIFrame* aFrame);
|
|
||||||
|
|
||||||
class RectCallback {
|
class RectCallback {
|
||||||
public:
|
public:
|
||||||
virtual void AddRect(const nsRect& aRect) = 0;
|
virtual void AddRect(const nsRect& aRect) = 0;
|
||||||
|
|||||||
@@ -458,7 +458,6 @@ skip-if = toolkit == "win"
|
|||||||
skip-if = toolkit == "win"
|
skip-if = toolkit == "win"
|
||||||
[test_flush_on_paint.html]
|
[test_flush_on_paint.html]
|
||||||
skip-if = true || (toolkit == 'android') || (toolkit == "cocoa") # Bug 688128, bug 539356
|
skip-if = true || (toolkit == 'android') || (toolkit == "cocoa") # Bug 688128, bug 539356
|
||||||
[test_getBoxQuads_convertPointRectQuad.html]
|
|
||||||
[test_bug687297.html]
|
[test_bug687297.html]
|
||||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 948948
|
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 948948
|
||||||
support-files =
|
support-files =
|
||||||
|
|||||||
@@ -1,525 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
|
||||||
</head>
|
|
||||||
<body onload="startTest()">
|
|
||||||
<p id="display"></p>
|
|
||||||
<script>
|
|
||||||
// Global variables we want eval() to be able to reference from anywhere
|
|
||||||
var f1d;
|
|
||||||
var text;
|
|
||||||
var suppressedText;
|
|
||||||
var notInDocument = document.createElement('div');
|
|
||||||
|
|
||||||
function isEval(expr, b) {
|
|
||||||
is(eval(expr), b, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isApprox(a, b, msg, options) {
|
|
||||||
if (a != b && 'tolerance' in options &&
|
|
||||||
Math.abs(a - b) < options.tolerance) {
|
|
||||||
ok(true, msg + "(" + a + " within " + options.tolerance + " of " + b + ")");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
is(a, b, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeQuadsExpr(fromStr, options) {
|
|
||||||
var getBoxQuadsOptionParts = [];
|
|
||||||
if ('box' in options) {
|
|
||||||
getBoxQuadsOptionParts.push("box:'" + options.box + "'");
|
|
||||||
}
|
|
||||||
if ('toStr' in options) {
|
|
||||||
getBoxQuadsOptionParts.push("relativeTo:" + options.toStr);
|
|
||||||
}
|
|
||||||
return fromStr + ".getBoxQuads({" + getBoxQuadsOptionParts.join(',') + "})";
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkQuadIsRect(fromStr, options, x, y, w, h) {
|
|
||||||
var quadsExpr = makeQuadsExpr(fromStr, options);
|
|
||||||
var quads = eval(quadsExpr);
|
|
||||||
is(quads.length, 1, quadsExpr + " checking quad count");
|
|
||||||
var q = quads[0];
|
|
||||||
isApprox(q.p1.x, x, quadsExpr + " checking quad.p1.x", options);
|
|
||||||
isApprox(q.p1.y, y, quadsExpr + " checking quad.p1.y", options);
|
|
||||||
isApprox(q.p2.x, x + w, quadsExpr + " checking quad.p2.x", options);
|
|
||||||
isApprox(q.p2.y, y, quadsExpr + " checking quad.p2.y", options);
|
|
||||||
isApprox(q.p3.x, x + w, quadsExpr + " checking quad.p3.x", options);
|
|
||||||
isApprox(q.p3.y, y + h, quadsExpr + " checking quad.p3.y", options);
|
|
||||||
isApprox(q.p4.x, x, quadsExpr + " checking quad.p4.x", options);
|
|
||||||
isApprox(q.p4.y, y + h, quadsExpr + " checking quad.p4.y", options);
|
|
||||||
|
|
||||||
isApprox(q.bounds.left, x, quadsExpr + " checking quad.bounds.left", options);
|
|
||||||
isApprox(q.bounds.top, y, quadsExpr + " checking quad.bounds.top", options);
|
|
||||||
isApprox(q.bounds.width, w, quadsExpr + " checking quad.bounds.width", options);
|
|
||||||
isApprox(q.bounds.height, h, quadsExpr + " checking quad.bounds.height", options);
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkQuadIsQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) {
|
|
||||||
var quadsExpr = makeQuadsExpr(fromStr, options);
|
|
||||||
var quads = eval(quadsExpr);
|
|
||||||
is(quads.length, 1, quadsExpr + " checking quad count");
|
|
||||||
var q = quads[0];
|
|
||||||
isApprox(q.p1.x, x1, quadsExpr + " checking quad.p1.x", options);
|
|
||||||
isApprox(q.p1.y, y1, quadsExpr + " checking quad.p1.y", options);
|
|
||||||
isApprox(q.p2.x, x2, quadsExpr + " checking quad.p2.x", options);
|
|
||||||
isApprox(q.p2.y, y2, quadsExpr + " checking quad.p2.y", options);
|
|
||||||
isApprox(q.p3.x, x3, quadsExpr + " checking quad.p3.x", options);
|
|
||||||
isApprox(q.p3.y, y3, quadsExpr + " checking quad.p3.y", options);
|
|
||||||
isApprox(q.p4.x, x4, quadsExpr + " checking quad.p4.x", options);
|
|
||||||
isApprox(q.p4.y, y4, quadsExpr + " checking quad.p4.y", options);
|
|
||||||
|
|
||||||
isApprox(q.bounds.left, Math.min(x1,x2,x3,x4), quadsExpr + " checking quad.bounds.left", options);
|
|
||||||
isApprox(q.bounds.top, Math.min(y1,y2,y3,y4), quadsExpr + " checking quad.bounds.top", options);
|
|
||||||
isApprox(q.bounds.right, Math.max(x1,x2,x3,x4), quadsExpr + " checking quad.bounds.right", options);
|
|
||||||
isApprox(q.bounds.bottom, Math.max(y1,y2,y3,y4), quadsExpr + " checking quad.bounds.bottom", options);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
em {
|
|
||||||
display:inline-block; height:10px; background:gray;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div id="dContainer"
|
|
||||||
style="padding:13px 14px 15px 16px;
|
|
||||||
border-width:17px 18px 19px 20px; border-style:solid; border-color:yellow;
|
|
||||||
margin:21px 22px 23px 24px;">
|
|
||||||
<div id="d"
|
|
||||||
style="width:120px; height:90px; padding:1px 2px 3px 4px;
|
|
||||||
border-width:5px 6px 7px 8px; border-style:solid; border-color:yellow;
|
|
||||||
margin:9px 10px 11px 12px; background:blue;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="dUnrelated" style="width:50px; height:50px;"></div>
|
|
||||||
|
|
||||||
<iframe id="f1" style="width:50px; height:50px; border:0; background:lime;"
|
|
||||||
src="data:text/html,<!DOCTYPE HTML><html style='padding:25px'><div id='f1d' style='position:absolute; left:14px; top:15px; width:16px; height:17px; background:pink'></div>">
|
|
||||||
</iframe>
|
|
||||||
<!--
|
|
||||||
It matters that the first part of this span is on the same line as the above <iframe>!
|
|
||||||
That ensures the first quad's X position is not equal to the anonymous block's X position.
|
|
||||||
-->
|
|
||||||
<span id="ibSplit"
|
|
||||||
><em id="ibSplitPart1" style="width:100px;"></em
|
|
||||||
><div style="width:110px; height:20px; background:black"></div
|
|
||||||
><em style="width:130px;"></em></span>
|
|
||||||
|
|
||||||
<table cellspacing="0" id="table" style="border:0; margin:0; padding:0; background:orange">
|
|
||||||
<tbody style="padding:0; margin:0; border:0; background:blue">
|
|
||||||
<tr style="height:50px; padding:0; margin:0; border:0">
|
|
||||||
<td style="border:0; margin:0; padding:0">Cell</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
<caption style="height:40px; background:yellow">Caption</caption>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<div style="height:80px; -moz-column-count:2; -moz-column-fill:auto; border:2px solid black;">
|
|
||||||
<div style="height:20px;"></div>
|
|
||||||
<div id="colSplit" style="height:80px; background:blue; border:10px solid red; border-bottom-width:15px"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="width:200px; border:2px solid black;"
|
|
||||||
><em style="width:150px;"></em
|
|
||||||
><span id="inlineSplit" style="background:pink; border:10px solid red; border-right-width:15px"
|
|
||||||
><em style="width:20px; background:green"></em><em style="width:60px"></em
|
|
||||||
></span
|
|
||||||
></div>
|
|
||||||
|
|
||||||
<div style="width:200px; border:2px solid black;"
|
|
||||||
><em style="width:150px;"></em
|
|
||||||
><span id="textContainer">T
|
|
||||||
TextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextText</span
|
|
||||||
></div>
|
|
||||||
|
|
||||||
<div id="suppressedTextContainer"> </div>
|
|
||||||
|
|
||||||
<div id="commentContainer"><!-- COMMENT --></div>
|
|
||||||
|
|
||||||
<div id="displayNone" style="display:none"></div>
|
|
||||||
|
|
||||||
<div id="overflowHidden"
|
|
||||||
style="overflow:hidden; width:120px; height:90px; padding:1px 2px 3px 4px;
|
|
||||||
border-width:5px 6px 7px 8px; border-style:solid; border-color:yellow;
|
|
||||||
margin:9px 10px 11px 12px; background:blue;">
|
|
||||||
<div style="height:400px; background:lime;"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="overflowScroll"
|
|
||||||
style="overflow:scroll; width:120px; height:90px; padding:1px 2px 3px 4px;
|
|
||||||
border-width:5px 6px 7px 8px; border-style:solid; border-color:yellow;
|
|
||||||
margin:9px 10px 11px 12px; background:blue; background-clip:content-box;">
|
|
||||||
<div id="overflowScrollChild" style="height:400px;"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="scaleTransformContainer" style="width:200px; height:200px;">
|
|
||||||
<div id="scaleTransform"
|
|
||||||
style="transform:scale(2); transform-origin:top left; width:70px; height:80px; background:yellow"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="translateTransformContainer" style="width:200px; height:200px;">
|
|
||||||
<div id="translateTransform"
|
|
||||||
style="transform:translate(30px,40px); width:70px; height:80px; background:yellow"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="rotateTransformContainer" style="width:200px; height:200px;">
|
|
||||||
<div id="rotateTransform"
|
|
||||||
style="transform:rotate(90deg); width:70px; height:80px; background:yellow"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="flipTransformContainer" style="width:200px; height:200px;">
|
|
||||||
<div id="flipTransform"
|
|
||||||
style="transform:scaleY(-1); width:70px; height:80px; background:yellow"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="rot45TransformContainer" style="width:200px; height:200px;">
|
|
||||||
<div id="rot45Transform"
|
|
||||||
style="transform:rotate(45deg); width:100px; height:100px; background:yellow"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="singularTransform" style="transform:scale(0); width:200px; height:200px;">
|
|
||||||
<div id="singularTransformChild1" style="height:50px;"></div>
|
|
||||||
<div id="singularTransformChild2" style="height:50px;"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="threeDTransformContainer" style="perspective:600px; width:200px; height:200px">
|
|
||||||
<div id="threeDTransform" style="transform:rotateY(70deg); background:yellow; height:100px; perspective:600px">
|
|
||||||
<div id="threeDTransformChild" style="transform:rotateY(-70deg); background:blue; height:50px;"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="preserve3DTransformContainer" style="perspective:600px; width:200px; height:200px">
|
|
||||||
<div id="preserve3DTransform" style="transform:rotateY(70deg); transform-style:preserve-3d; background:yellow; height:100px;">
|
|
||||||
<div id="preserve3DTransformChild" style="transform:rotateY(-70deg); background:blue; height:50px;"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="svgContainer">
|
|
||||||
<svg id="svg" style="width:200px; height:200px; background:lightgray;">
|
|
||||||
<circle id="circle" cx="50" cy="50" r="20" fill="red" style="margin:20px; padding:10px; border:15px solid black"></circle>
|
|
||||||
<g transform="scale(2)">
|
|
||||||
<foreignObject x="50" y="20">
|
|
||||||
<div id="foreign" style="width:100px; height:60px; background:purple"></div>
|
|
||||||
</foreignObject>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
window.scrollTo(0,0);
|
|
||||||
|
|
||||||
function startTest() {
|
|
||||||
SpecialPowers.pushPrefEnv({"set": [["layout.css.DOMPoint.enabled", true],
|
|
||||||
["layout.css.DOMQuad.enabled", true],
|
|
||||||
["layout.css.getBoxQuads.enabled", true]]}, runTest);
|
|
||||||
}
|
|
||||||
|
|
||||||
function runTest() {
|
|
||||||
// Setup globals
|
|
||||||
f1d = f1.contentWindow.f1d;
|
|
||||||
text = textContainer.firstChild;
|
|
||||||
suppressedText = suppressedTextContainer.firstChild;
|
|
||||||
|
|
||||||
// Test basic BoxQuadOptions.box.
|
|
||||||
var dX = d.getBoundingClientRect().left;
|
|
||||||
var dY = d.getBoundingClientRect().top;
|
|
||||||
var dW = d.getBoundingClientRect().width;
|
|
||||||
var dH = d.getBoundingClientRect().height;
|
|
||||||
|
|
||||||
checkQuadIsRect("d", {box:"content"},
|
|
||||||
dX + 4 + 8, dY + 1 + 5, 120, 90);
|
|
||||||
checkQuadIsRect("d", {box:"padding"},
|
|
||||||
dX + 8, dY + 5, 120 + 2 + 4, 90 + 1 + 3);
|
|
||||||
checkQuadIsRect("d", {box:"border"},
|
|
||||||
dX, dY, dW, dH);
|
|
||||||
checkQuadIsRect("d", {},
|
|
||||||
dX, dY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7);
|
|
||||||
checkQuadIsRect("d", {box:"margin"},
|
|
||||||
dX - 12, dY - 9, 120 + 2 + 4 + 6 + 8 + 10 + 12, 90 + 1 + 3 + 5 + 7 + 9 + 11);
|
|
||||||
|
|
||||||
// Test basic BoxQuadOptions.relativeTo
|
|
||||||
checkQuadIsRect("d", {toStr:"dContainer"},
|
|
||||||
12 + 16 + 20, 9 + 13 + 17, dW, dH);
|
|
||||||
|
|
||||||
// Test BoxQuadOptions.relativeTo relative to this document
|
|
||||||
checkQuadIsRect("d", {toStr:"document"},
|
|
||||||
dX, dY, dW, dH);
|
|
||||||
// Test BoxQuadOptions.relativeTo relative to a non-ancestor.
|
|
||||||
var dUnrelatedX = dUnrelated.getBoundingClientRect().left;
|
|
||||||
var dUnrelatedY = dUnrelated.getBoundingClientRect().top;
|
|
||||||
checkQuadIsRect("d", {toStr:"dUnrelated"},
|
|
||||||
dX - dUnrelatedX, dY - dUnrelatedY, dW, dH);
|
|
||||||
// Test BoxQuadOptions.relativeTo relative to an element in a different document (and the document)
|
|
||||||
var f1X = f1.getBoundingClientRect().left;
|
|
||||||
var f1Y = f1.getBoundingClientRect().top;
|
|
||||||
checkQuadIsRect("d", {toStr:"f1.contentWindow.f1d"},
|
|
||||||
dX - (f1X + 14), dY - (f1Y + 15), dW, dH);
|
|
||||||
checkQuadIsRect("d", {toStr:"f1.contentDocument"},
|
|
||||||
dX - f1X, dY - f1Y, dW, dH);
|
|
||||||
// Test one document relative to another
|
|
||||||
checkQuadIsRect("f1.contentDocument", {toStr:"document"},
|
|
||||||
f1X, f1Y, 50, 50);
|
|
||||||
// The box type is irrelevant for a document
|
|
||||||
checkQuadIsRect("f1.contentDocument", {toStr:"document",box:"content"},
|
|
||||||
f1X, f1Y, 50, 50);
|
|
||||||
checkQuadIsRect("f1.contentDocument", {toStr:"document",box:"margin"},
|
|
||||||
f1X, f1Y, 50, 50);
|
|
||||||
checkQuadIsRect("f1.contentDocument", {toStr:"document",box:"padding"},
|
|
||||||
f1X, f1Y, 50, 50);
|
|
||||||
|
|
||||||
// Test that anonymous boxes are correctly ignored when building quads.
|
|
||||||
var ibSplitPart1X = ibSplitPart1.getBoundingClientRect().left;
|
|
||||||
var ibSplitY = ibSplit.getBoundingClientRect().top;
|
|
||||||
isEval("ibSplit.getBoxQuads().length", 3);
|
|
||||||
isEval("ibSplit.getBoxQuads()[0].bounds.left", ibSplitPart1X);
|
|
||||||
isEval("ibSplit.getBoxQuads()[0].bounds.width", 100);
|
|
||||||
isEval("ibSplit.getBoxQuads()[1].bounds.width", 110);
|
|
||||||
isEval("ibSplit.getBoxQuads()[2].bounds.width", 130);
|
|
||||||
isEval("table.getBoxQuads().length", 2);
|
|
||||||
isEval("table.getBoxQuads()[0].bounds.height", 50);
|
|
||||||
isEval("table.getBoxQuads()[1].bounds.height", 40);
|
|
||||||
|
|
||||||
// Test that we skip anonymous boxes when finding the right box to be relative to.
|
|
||||||
checkQuadIsRect("d", {toStr:"ibSplit"},
|
|
||||||
dX - ibSplitPart1X, dY - ibSplitY, dW, dH);
|
|
||||||
var tableX = table.getClientRects()[0].left;
|
|
||||||
var tableY = table.getClientRects()[0].top;
|
|
||||||
checkQuadIsRect("d", {toStr:"table"},
|
|
||||||
dX - tableX, dY - tableY, dW, dH);
|
|
||||||
|
|
||||||
// Test boxes generated by block splitting. Check for borders being placed correctly.
|
|
||||||
var colSplitY = colSplit.getClientRects()[0].top;
|
|
||||||
isEval("colSplit.getBoxQuads().length", 2);
|
|
||||||
isEval("colSplit.getBoxQuads()[0].bounds.top", colSplitY);
|
|
||||||
isEval("colSplit.getBoxQuads()[0].bounds.height", 60);
|
|
||||||
isEval("colSplit.getBoxQuads()[1].bounds.top", colSplitY - 20);
|
|
||||||
isEval("colSplit.getBoxQuads()[1].bounds.height", 45);
|
|
||||||
isEval("colSplit.getBoxQuads({box:'content'}).length", 2);
|
|
||||||
// The first box for the block has the top border; the second box has the bottom border.
|
|
||||||
isEval("colSplit.getBoxQuads({box:'content'})[0].bounds.top", colSplitY + 10);
|
|
||||||
isEval("colSplit.getBoxQuads({box:'content'})[0].bounds.height", 50);
|
|
||||||
isEval("colSplit.getBoxQuads({box:'content'})[1].bounds.top", colSplitY - 20);
|
|
||||||
isEval("colSplit.getBoxQuads({box:'content'})[1].bounds.height", 30);
|
|
||||||
|
|
||||||
var inlineSplitX = inlineSplit.getClientRects()[0].left;
|
|
||||||
isEval("inlineSplit.getBoxQuads().length", 2);
|
|
||||||
isEval("inlineSplit.getBoxQuads()[0].bounds.left", inlineSplitX);
|
|
||||||
isEval("inlineSplit.getBoxQuads()[0].bounds.width", 30);
|
|
||||||
isEval("inlineSplit.getBoxQuads()[1].bounds.left", inlineSplitX - 150);
|
|
||||||
isEval("inlineSplit.getBoxQuads()[1].bounds.width", 75);
|
|
||||||
isEval("inlineSplit.getBoxQuads({box:'content'}).length", 2);
|
|
||||||
// The first box for the inline has the left border; the second box has the right border.
|
|
||||||
isEval("inlineSplit.getBoxQuads({box:'content'})[0].bounds.left", inlineSplitX + 10);
|
|
||||||
isEval("inlineSplit.getBoxQuads({box:'content'})[0].bounds.width", 20);
|
|
||||||
isEval("inlineSplit.getBoxQuads({box:'content'})[1].bounds.left", inlineSplitX - 150);
|
|
||||||
isEval("inlineSplit.getBoxQuads({box:'content'})[1].bounds.width", 60);
|
|
||||||
|
|
||||||
var textX = textContainer.getClientRects()[0].left;
|
|
||||||
isEval("text.getBoxQuads().length", 2);
|
|
||||||
isEval("text.getBoxQuads()[0].bounds.left", textX);
|
|
||||||
isEval("text.getBoxQuads()[1].bounds.left", textX - 150);
|
|
||||||
// Box types are irrelevant for text
|
|
||||||
isEval("text.getBoxQuads({box:'content'}).length", 2);
|
|
||||||
isEval("text.getBoxQuads({box:'content'})[0].bounds.left", textX);
|
|
||||||
isEval("text.getBoxQuads({box:'content'})[1].bounds.left", textX - 150);
|
|
||||||
isEval("text.getBoxQuads({box:'padding'}).length", 2);
|
|
||||||
isEval("text.getBoxQuads({box:'padding'})[0].bounds.left", textX);
|
|
||||||
isEval("text.getBoxQuads({box:'padding'})[1].bounds.left", textX - 150);
|
|
||||||
isEval("text.getBoxQuads({box:'margin'}).length", 2);
|
|
||||||
isEval("text.getBoxQuads({box:'margin'})[0].bounds.left", textX);
|
|
||||||
isEval("text.getBoxQuads({box:'margin'})[1].bounds.left", textX - 150);
|
|
||||||
|
|
||||||
// Check that a text node whose layout might have been optimized away gives
|
|
||||||
// correct results.
|
|
||||||
var suppressedTextContainerX = suppressedTextContainer.getBoundingClientRect().left;
|
|
||||||
isEval("suppressedText.getBoxQuads().length", 1);
|
|
||||||
isEval("suppressedText.getBoxQuads()[0].bounds.left", suppressedTextContainerX);
|
|
||||||
isEval("suppressedText.getBoxQuads()[0].bounds.width", 0);
|
|
||||||
|
|
||||||
var comment = commentContainer.firstChild;
|
|
||||||
try {
|
|
||||||
comment.getBoxQuads();
|
|
||||||
ok(false, "Exception should have been thrown");
|
|
||||||
} catch (ex) {
|
|
||||||
is(ex.name, "TypeError",
|
|
||||||
"Exception for comment.getBoxQuads()");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
d.getBoxQuads({relativeTo:comment});
|
|
||||||
ok(false, "Exception should have been thrown");
|
|
||||||
} catch (ex) {
|
|
||||||
is(ex.name, "TypeError",
|
|
||||||
"Exception for getBoxQuads({relativeTo:comment})");
|
|
||||||
}
|
|
||||||
|
|
||||||
var fragment = document.createDocumentFragment();
|
|
||||||
try {
|
|
||||||
fragment.getBoxQuads();
|
|
||||||
ok(false, "Exception should have been thrown");
|
|
||||||
} catch (ex) {
|
|
||||||
is(ex.name, "TypeError",
|
|
||||||
"Exception for fragment.getBoxQuads()");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
d.getBoxQuads({relativeTo:fragment});
|
|
||||||
ok(false, "Exception should have been thrown");
|
|
||||||
} catch (ex) {
|
|
||||||
is(ex.name, "TypeError",
|
|
||||||
"Exception for getBoxQuads({relativeTo:fragment})");
|
|
||||||
}
|
|
||||||
|
|
||||||
isEval("displayNone.getBoxQuads().length", 0);
|
|
||||||
isEval("notInDocument.getBoxQuads().length", 0);
|
|
||||||
|
|
||||||
// Test an overflow:hidden version of d. overflow:hidden should not affect
|
|
||||||
// the quads, basically.
|
|
||||||
var oHX = overflowHidden.getBoundingClientRect().left;
|
|
||||||
var oHY = overflowHidden.getBoundingClientRect().top;
|
|
||||||
checkQuadIsRect("overflowHidden", {box:"content"},
|
|
||||||
oHX + 4 + 8, oHY + 1 + 5, 120, 90);
|
|
||||||
checkQuadIsRect("overflowHidden", {box:"padding"},
|
|
||||||
oHX + 8, oHY + 5, 120 + 2 + 4, 90 + 1 + 3);
|
|
||||||
checkQuadIsRect("overflowHidden", {box:"border"},
|
|
||||||
oHX, oHY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7);
|
|
||||||
checkQuadIsRect("overflowHidden", {},
|
|
||||||
oHX, oHY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7);
|
|
||||||
checkQuadIsRect("overflowHidden", {box:"margin"},
|
|
||||||
oHX - 12, oHY - 9, 120 + 2 + 4 + 6 + 8 + 10 + 12, 90 + 1 + 3 + 5 + 7 + 9 + 11);
|
|
||||||
|
|
||||||
// Test an overflow:scroll version of d. I assume that boxes aren't affected
|
|
||||||
// by the scrollbar although it's not clear that this is correct.
|
|
||||||
var oSX = overflowScroll.getBoundingClientRect().left;
|
|
||||||
var oSY = overflowScroll.getBoundingClientRect().top;
|
|
||||||
checkQuadIsRect("overflowScroll", {box:"content"},
|
|
||||||
oSX + 4 + 8, oSY + 1 + 5, 120, 90);
|
|
||||||
checkQuadIsRect("overflowScroll", {box:"padding"},
|
|
||||||
oSX + 8, oSY + 5, 120 + 2 + 4, 90 + 1 + 3);
|
|
||||||
checkQuadIsRect("overflowScroll", {box:"border"},
|
|
||||||
oSX, oSY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7);
|
|
||||||
checkQuadIsRect("overflowScroll", {},
|
|
||||||
oSX, oSY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7);
|
|
||||||
checkQuadIsRect("overflowScroll", {box:"margin"},
|
|
||||||
oSX - 12, oSY - 9, 120 + 2 + 4 + 6 + 8 + 10 + 12, 90 + 1 + 3 + 5 + 7 + 9 + 11);
|
|
||||||
|
|
||||||
// Test simple 2D transforms.
|
|
||||||
var stcX = scaleTransformContainer.getBoundingClientRect().left;
|
|
||||||
var stcY = scaleTransformContainer.getBoundingClientRect().top;
|
|
||||||
checkQuadIsRect("scaleTransform", {},
|
|
||||||
stcX, stcY, 140, 160);
|
|
||||||
var ttcX = translateTransformContainer.getBoundingClientRect().left;
|
|
||||||
var ttcY = translateTransformContainer.getBoundingClientRect().top;
|
|
||||||
checkQuadIsRect("translateTransform", {},
|
|
||||||
ttcX + 30, ttcY + 40, 70, 80);
|
|
||||||
// Test mapping into a transformed element.
|
|
||||||
checkQuadIsRect("scaleTransform", {toStr:"translateTransform"},
|
|
||||||
stcX - (ttcX + 30), stcY - (ttcY + 40), 140, 160);
|
|
||||||
// Test 90 degree rotation.
|
|
||||||
var rotatetcX = rotateTransformContainer.getBoundingClientRect().left;
|
|
||||||
var rotatetcY = rotateTransformContainer.getBoundingClientRect().top;
|
|
||||||
checkQuadIsQuad("rotateTransform", {},
|
|
||||||
rotatetcX + 75, rotatetcY + 5,
|
|
||||||
rotatetcX + 75, rotatetcY + 75,
|
|
||||||
rotatetcX - 5, rotatetcY + 75,
|
|
||||||
rotatetcX - 5, rotatetcY + 5);
|
|
||||||
// Test vertical flip.
|
|
||||||
var fliptcX = flipTransformContainer.getBoundingClientRect().left;
|
|
||||||
var fliptcY = flipTransformContainer.getBoundingClientRect().top;
|
|
||||||
checkQuadIsQuad("flipTransform", {},
|
|
||||||
fliptcX, fliptcY + 80,
|
|
||||||
fliptcX + 70, fliptcY + 80,
|
|
||||||
fliptcX + 70, fliptcY,
|
|
||||||
fliptcX, fliptcY);
|
|
||||||
// Test non-90deg rotation.
|
|
||||||
var rot45tcX = rot45TransformContainer.getBoundingClientRect().left;
|
|
||||||
var rot45tcY = rot45TransformContainer.getBoundingClientRect().top;
|
|
||||||
var halfDiagonal = 100/Math.sqrt(2);
|
|
||||||
checkQuadIsQuad("rot45Transform", {tolerance:0.0001},
|
|
||||||
rot45tcX + 50, rot45tcY + 50 - halfDiagonal,
|
|
||||||
rot45tcX + 50 + halfDiagonal, rot45tcY + 50,
|
|
||||||
rot45tcX + 50, rot45tcY + 50 + halfDiagonal,
|
|
||||||
rot45tcX + 50 - halfDiagonal, rot45tcY + 50);
|
|
||||||
|
|
||||||
// Test singular transforms.
|
|
||||||
var singularTransformX = singularTransform.getBoundingClientRect().left;
|
|
||||||
var singularTransformY = singularTransform.getBoundingClientRect().top;
|
|
||||||
// They map everything to a point.
|
|
||||||
checkQuadIsRect("singularTransform", {},
|
|
||||||
singularTransformX, singularTransformY, 0, 0);
|
|
||||||
checkQuadIsRect("singularTransformChild2", {},
|
|
||||||
singularTransformX, singularTransformY, 0, 0);
|
|
||||||
// Mapping into an element with a singular transform from outside sets
|
|
||||||
// everything to zero.
|
|
||||||
checkQuadIsRect("d", {toStr:"singularTransform"},
|
|
||||||
0, 0, 0, 0);
|
|
||||||
// But mappings within a subtree of an element with a singular transform work.
|
|
||||||
checkQuadIsRect("singularTransformChild2", {toStr:"singularTransformChild1"},
|
|
||||||
0, 50, 200, 50);
|
|
||||||
|
|
||||||
// Test 3D transforms.
|
|
||||||
var t3tcX = threeDTransformContainer.getBoundingClientRect().left;
|
|
||||||
var t3tcY = threeDTransformContainer.getBoundingClientRect().top;
|
|
||||||
checkQuadIsQuad("threeDTransform", {tolerance:0.0001},
|
|
||||||
t3tcX + 59.446714, t3tcY - 18.569847,
|
|
||||||
t3tcX + 129.570778, t3tcY + 13.540874,
|
|
||||||
t3tcX + 129.570778, t3tcY + 100,
|
|
||||||
t3tcX + 59.446714, t3tcY + 100);
|
|
||||||
// Test nested 3D transforms (without preserve-3d).
|
|
||||||
checkQuadIsQuad("threeDTransformChild", {tolerance:0.0001},
|
|
||||||
t3tcX + 89.395061, t3tcY + 2.243033,
|
|
||||||
t3tcX + 113.041727, t3tcY - 2.758530,
|
|
||||||
t3tcX + 113.041727, t3tcY + 52.985921,
|
|
||||||
t3tcX + 89.395061, t3tcY + 47.571899);
|
|
||||||
// Test preserve-3D.
|
|
||||||
var p3dtcX = preserve3DTransformContainer.getBoundingClientRect().left;
|
|
||||||
var p3dtcY = preserve3DTransformContainer.getBoundingClientRect().top;
|
|
||||||
checkQuadIsRect("preserve3DTransformChild", {tolerance:0.0001},
|
|
||||||
p3dtcX, p3dtcY, 200, 50,
|
|
||||||
{tolerance:0.0001});
|
|
||||||
// Test mapping back into preserve-3D.
|
|
||||||
checkQuadIsRect("d", {toStr:"preserve3DTransformChild",tolerance:0.0001},
|
|
||||||
dX - p3dtcX, dY - p3dtcY, dW, dH);
|
|
||||||
|
|
||||||
// Test SVG.
|
|
||||||
var svgContainerX = svgContainer.getBoundingClientRect().left;
|
|
||||||
var svgContainerY = svgContainer.getBoundingClientRect().top;
|
|
||||||
checkQuadIsRect("circle", {},
|
|
||||||
svgContainerX + 30, svgContainerY + 30, 40, 40);
|
|
||||||
// Box types are ignored for SVG elements.
|
|
||||||
checkQuadIsRect("circle", {box:"content"},
|
|
||||||
svgContainerX + 30, svgContainerY + 30, 40, 40);
|
|
||||||
checkQuadIsRect("circle", {box:"padding"},
|
|
||||||
svgContainerX + 30, svgContainerY + 30, 40, 40);
|
|
||||||
checkQuadIsRect("circle", {box:"margin"},
|
|
||||||
svgContainerX + 30, svgContainerY + 30, 40, 40);
|
|
||||||
checkQuadIsRect("d", {toStr:"circle"},
|
|
||||||
dX - (svgContainerX + 30), dY - (svgContainerY + 30), dW, dH);
|
|
||||||
// Test foreignObject inside an SVG transform.
|
|
||||||
checkQuadIsRect("foreign", {},
|
|
||||||
svgContainerX + 100, svgContainerY + 40, 200, 120);
|
|
||||||
|
|
||||||
// XXX Test SVG text (probably broken; unclear what the best way is to handle it)
|
|
||||||
|
|
||||||
// Test that converting between nodes in different toplevel browsing contexts
|
|
||||||
// throws an exception.
|
|
||||||
var openedWindow = window.open("data:text/html,<div id='d'>","");
|
|
||||||
openedWindow.addEventListener("load", function() {
|
|
||||||
try {
|
|
||||||
openedWindow.d.getBoxQuads({relativeTo:document});
|
|
||||||
ok(false, "Exception should have been thrown");
|
|
||||||
} catch (ex) {
|
|
||||||
is(ex.name, "NotFoundError",
|
|
||||||
"Exception for getBoxQuads on nodes in different toplevel browsing contexts");
|
|
||||||
}
|
|
||||||
openedWindow.close();
|
|
||||||
|
|
||||||
SimpleTest.finish();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1810,19 +1810,6 @@ pref("layout.css.sticky.enabled", true);
|
|||||||
// Is support for CSS "will-change" enabled?
|
// Is support for CSS "will-change" enabled?
|
||||||
pref("layout.css.will-change.enabled", false);
|
pref("layout.css.will-change.enabled", false);
|
||||||
|
|
||||||
// Is support for DOMPoint enabled?
|
|
||||||
pref("layout.css.DOMPoint.enabled", true);
|
|
||||||
|
|
||||||
// Is support for DOMQuad enabled?
|
|
||||||
pref("layout.css.DOMQuad.enabled", true);
|
|
||||||
|
|
||||||
// Is support for GeometryUtils.getBoxQuads enabled?
|
|
||||||
#ifdef RELEASE_BUILD
|
|
||||||
pref("layout.css.getBoxQuads.enabled", false);
|
|
||||||
#else
|
|
||||||
pref("layout.css.getBoxQuads.enabled", true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Is support for CSS "text-align: true X" enabled?
|
// Is support for CSS "text-align: true X" enabled?
|
||||||
pref("layout.css.text-align-true-value.enabled", false);
|
pref("layout.css.text-align-true-value.enabled", false);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user