Attachment #807614: Part 1: Implement Node.convertPoint/Rect/QuadFromNode for bug #918189

View | Details | Raw Unified | Return to bug 918189
Collapse All | Expand All

(-)a/content/base/public/nsINode.h (+18 lines)
Line     Link Here 
 Lines 60-77   inline bool IsSpaceCharacter(PRUnichar a Link Here 
60
}
60
}
61
inline bool IsSpaceCharacter(char aChar) {
61
inline bool IsSpaceCharacter(char aChar) {
62
  return aChar == ' ' || aChar == '\t' || aChar == '\n' || aChar == '\r' ||
62
  return aChar == ' ' || aChar == '\t' || aChar == '\n' || aChar == '\r' ||
63
         aChar == '\f';
63
         aChar == '\f';
64
}
64
}
65
class Element;
65
class Element;
66
class EventHandlerNonNull;
66
class EventHandlerNonNull;
67
class OnErrorEventHandlerNonNull;
67
class OnErrorEventHandlerNonNull;
68
class DOMPoint;
69
class DOMRect;
68
class DOMQuad;
70
class DOMQuad;
69
struct BoxQuadOptions;
71
struct BoxQuadOptions;
72
struct ConvertPointOptions;
70
template<typename T> class Optional;
73
template<typename T> class Optional;
71
} // namespace dom
74
} // namespace dom
72
} // namespace mozilla
75
} // namespace mozilla
73
76
74
#define NODE_FLAG_BIT(n_) (1U << (WRAPPER_CACHE_FLAGS_BITS_USED + (n_)))
77
#define NODE_FLAG_BIT(n_) (1U << (WRAPPER_CACHE_FLAGS_BITS_USED + (n_)))
75
78
76
enum {
79
enum {
77
  // This bit will be set if the node has a listener manager.
80
  // This bit will be set if the node has a listener manager.
 Lines 261-276   private: Link Here 
261
 * An internal interface that abstracts some DOMNode-related parts that both
264
 * An internal interface that abstracts some DOMNode-related parts that both
262
 * nsIContent and nsIDocument share.  An instance of this interface has a list
265
 * nsIContent and nsIDocument share.  An instance of this interface has a list
263
 * of nsIContent children and provides access to them.
266
 * of nsIContent children and provides access to them.
264
 */
267
 */
265
class nsINode : public mozilla::dom::EventTarget
268
class nsINode : public mozilla::dom::EventTarget
266
{
269
{
267
public:
270
public:
268
  typedef mozilla::dom::BoxQuadOptions BoxQuadOptions;
271
  typedef mozilla::dom::BoxQuadOptions BoxQuadOptions;
272
  typedef mozilla::dom::ConvertPointOptions ConvertPointOptions;
273
  typedef mozilla::dom::DOMRect DOMRect;
274
  typedef mozilla::dom::DOMPoint DOMPoint;
269
  typedef mozilla::dom::DOMQuad DOMQuad;
275
  typedef mozilla::dom::DOMQuad DOMQuad;
270
276
271
  NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODE_IID)
277
  NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODE_IID)
272
278
273
  // Among the sub-classes that inherit (directly or indirectly) from nsINode,
279
  // Among the sub-classes that inherit (directly or indirectly) from nsINode,
274
  // measurement of the following members may be added later if DMD finds it is
280
  // measurement of the following members may be added later if DMD finds it is
275
  // worthwhile:
281
  // worthwhile:
276
  // - nsGenericHTMLElement:  mForm, mFieldSet
282
  // - nsGenericHTMLElement:  mForm, mFieldSet
 Lines 1577-1592   public: Link Here 
1577
  // ParentNode methods
1583
  // ParentNode methods
1578
  mozilla::dom::Element* GetFirstElementChild() const;
1584
  mozilla::dom::Element* GetFirstElementChild() const;
1579
  mozilla::dom::Element* GetLastElementChild() const;
1585
  mozilla::dom::Element* GetLastElementChild() const;
1580
1586
1581
1587
1582
  void GetBoxQuads(const BoxQuadOptions& aOptions,
1588
  void GetBoxQuads(const BoxQuadOptions& aOptions,
1583
                   nsTArray<nsRefPtr<DOMQuad> >& aResult,
1589
                   nsTArray<nsRefPtr<DOMQuad> >& aResult,
1584
                   mozilla::ErrorResult& aRv);
1590
                   mozilla::ErrorResult& aRv);
1591
  already_AddRefed<DOMPoint> ConvertPointFromNode(const DOMPoint& aPoint,
1592
                                                  nsINode& aFrom,
1593
                                                  const ConvertPointOptions& aOptions,
1594
                                                  mozilla::ErrorResult& aRv);
1595
  already_AddRefed<DOMQuad> ConvertRectFromNode(const DOMRect& aRect,
1596
                                                nsINode& aFrom,
1597
                                                const ConvertPointOptions& aOptions,
1598
                                                mozilla::ErrorResult& aRv);
1599
  already_AddRefed<DOMQuad> ConvertQuadFromNode(const DOMQuad& aQuad,
1600
                                                nsINode& aFrom,
1601
                                                const ConvertPointOptions& aOptions,
1602
                                                mozilla::ErrorResult& aRv);
1585
1603
1586
protected:
1604
protected:
1587
1605
1588
  // Override this function to create a custom slots class.
1606
  // Override this function to create a custom slots class.
1589
  // Must not return null.
1607
  // Must not return null.
1590
  virtual nsINode::nsSlots* CreateSlots();
1608
  virtual nsINode::nsSlots* CreateSlots();
1591
1609
1592
  bool HasSlots() const
1610
  bool HasSlots() const
(-)a/content/base/src/nsINode.cpp (+55 lines)
Line     Link Here 
 Lines 98-113    Link Here 
98
#include "HTMLLegendElement.h"
98
#include "HTMLLegendElement.h"
99
#include "nsWrapperCacheInlines.h"
99
#include "nsWrapperCacheInlines.h"
100
#include "WrapperFactory.h"
100
#include "WrapperFactory.h"
101
#include "DocumentType.h"
101
#include "DocumentType.h"
102
#include <algorithm>
102
#include <algorithm>
103
#include "nsDOMEvent.h"
103
#include "nsDOMEvent.h"
104
#include "nsGlobalWindow.h"
104
#include "nsGlobalWindow.h"
105
#include "nsDOMMutationObserver.h"
105
#include "nsDOMMutationObserver.h"
106
#include "mozilla/dom/DOMPoint.h"
107
#include "mozilla/dom/DOMRect.h"
106
#include "mozilla/dom/DOMQuad.h"
108
#include "mozilla/dom/DOMQuad.h"
107
#include "mozilla/CoordinateTransformations.h"
109
#include "mozilla/CoordinateTransformations.h"
108
110
109
using namespace mozilla;
111
using namespace mozilla;
110
using namespace mozilla::dom;
112
using namespace mozilla::dom;
111
113
112
nsINode::nsSlots::~nsSlots()
114
nsINode::nsSlots::~nsSlots()
113
{
115
{
 Lines 2548-2555   nsINode::GetBoxQuads(const BoxQuadOption Link Here 
2548
                     ErrorResult& aRv)
2550
                     ErrorResult& aRv)
2549
{
2551
{
2550
  nsAutoTArray<Quad2D,1> quads;
2552
  nsAutoTArray<Quad2D,1> quads;
2551
  mozilla::GetBoxQuads(this, aOptions, quads, aRv);
2553
  mozilla::GetBoxQuads(this, aOptions, quads, aRv);
2552
  for (uint32_t i = 0; i < quads.Length(); ++i) {
2554
  for (uint32_t i = 0; i < quads.Length(); ++i) {
2553
    aResult.AppendElement(new DOMQuad(OwnerDoc(), quads[i].mPoints));
2555
    aResult.AppendElement(new DOMQuad(OwnerDoc(), quads[i].mPoints));
2554
  }
2556
  }
2555
}
2557
}
2558
2559
already_AddRefed<DOMPoint>
2560
nsINode::ConvertPointFromNode(const DOMPoint& aPoint,
2561
                              nsINode& aFrom,
2562
                              const ConvertPointOptions& aOptions,
2563
                              ErrorResult& aRv)
2564
{
2565
  gfxPoint pt(aPoint.X(), aPoint.Y());
2566
  TransformCSSPoints(this, &aFrom, 1, &pt, aOptions, aRv);
2567
  nsRefPtr<DOMPoint> result = new DOMPoint(OwnerDoc(), pt.x, pt.y);
2568
  return result.forget();
2569
}
2570
2571
already_AddRefed<DOMQuad>
2572
nsINode::ConvertRectFromNode(const DOMRect& aRect,
2573
                             nsINode& aFrom,
2574
                             const ConvertPointOptions& aOptions,
2575
                             ErrorResult& aRv)
2576
{
2577
  gfxPoint pts[4] = {
2578
    gfxPoint(aRect.Left(), aRect.Top()),
2579
    gfxPoint(aRect.Right(), aRect.Top()),
2580
    gfxPoint(aRect.Right(), aRect.Bottom()),
2581
    gfxPoint(aRect.Left(), aRect.Bottom())
2582
  };
2583
  TransformCSSPoints(this, &aFrom, 4, pts, aOptions, aRv);
2584
  nsRefPtr<DOMQuad> result = new DOMQuad(OwnerDoc(), pts);
2585
  return result.forget();
2586
}
2587
2588
static gfxPoint
2589
DOMPointToGfxPoint(DOMPoint* aPoint)
2590
{
2591
  MOZ_ASSERT(aPoint->W() == 0.0, "W not supported");
2592
  return gfxPoint(aPoint->X(), aPoint->Y());
2593
}
2594
2595
already_AddRefed<DOMQuad>
2596
nsINode::ConvertQuadFromNode(const DOMQuad& aQuad,
2597
                             nsINode& aFrom,
2598
                             const ConvertPointOptions& aOptions,
2599
                             ErrorResult& aRv)
2600
{
2601
  gfxPoint pts[4] = {
2602
    DOMPointToGfxPoint(aQuad.P1()),
2603
    DOMPointToGfxPoint(aQuad.P2()),
2604
    DOMPointToGfxPoint(aQuad.P3()),
2605
    DOMPointToGfxPoint(aQuad.P4())
2606
  };
2607
  TransformCSSPoints(this, &aFrom, 4, pts, aOptions, aRv);
2608
  nsRefPtr<DOMQuad> result = new DOMQuad(OwnerDoc(), pts);
2609
  return result.forget();
2610
}
(-)a/dom/webidl/Node.webidl (+11 lines)
Line     Link Here 
 Lines 111-122   interface Node : EventTarget { Link Here 
111
enum BoxType { "content", "padding", "border", "margin" };
111
enum BoxType { "content", "padding", "border", "margin" };
112
112
113
dictionary BoxQuadOptions {
113
dictionary BoxQuadOptions {
114
  BoxType box = "border";
114
  BoxType box = "border";
115
  Node? relativeTo = null;
115
  Node? relativeTo = null;
116
  BoxType relativeToBox = "border";
116
  BoxType relativeToBox = "border";
117
};
117
};
118
118
119
dictionary ConvertPointOptions {
120
  BoxType fromBox = "border";
121
  BoxType toBox = "border";
122
};
123
119
partial interface Node {
124
partial interface Node {
120
  [Throws]
125
  [Throws]
121
  sequence<DOMQuad> getBoxQuads(optional BoxQuadOptions options);
126
  sequence<DOMQuad> getBoxQuads(optional BoxQuadOptions options);
127
  [Throws]
128
  DOMPoint convertPointFromNode(DOMPoint point, Node fromNode, optional ConvertPointOptions options);
129
  [Throws]
130
  DOMQuad convertRectFromNode(DOMRect rect, Node fromNode, optional ConvertPointOptions options);
131
  [Throws]
132
  DOMQuad convertQuadFromNode(DOMQuad quad, Node fromNode, optional ConvertPointOptions options);
122
};
133
};
(-)a/layout/base/CoordinateTransformations.cpp (+34 lines)
Line     Link Here 
 Lines 183-191   GetBoxQuads(nsINode* aNode, const BoxQua Link Here 
183
  // GetBoxRectForFrame can modify relativeToFrame so call it first.
183
  // GetBoxRectForFrame can modify relativeToFrame so call it first.
184
  nsPoint relativeToTopLeft =
184
  nsPoint relativeToTopLeft =
185
      GetBoxRectForFrame(&relativeToFrame, aOptions.mRelativeToBox).TopLeft();
185
      GetBoxRectForFrame(&relativeToFrame, aOptions.mRelativeToBox).TopLeft();
186
  AccumulateQuadCallback callback(ownerDoc, aResult, relativeToFrame,
186
  AccumulateQuadCallback callback(ownerDoc, aResult, relativeToFrame,
187
                                  relativeToTopLeft, aOptions.mBox);
187
                                  relativeToTopLeft, aOptions.mBox);
188
  nsLayoutUtils::GetAllInFlowBoxes(frame, &callback);
188
  nsLayoutUtils::GetAllInFlowBoxes(frame, &callback);
189
}
189
}
190
190
191
void
192
TransformCSSPoints(nsINode* aTo, nsINode* aFrom,
193
                   uint32_t aPointCount, gfxPoint* aPoints,
194
                   const ConvertPointOptions& aOptions, ErrorResult& aRv)
195
{
196
  nsIFrame* fromFrame = GetFirstNonAnonymousLayoutFrameForNode(aFrom, aRv);
197
  nsIFrame* toFrame = GetFirstNonAnonymousLayoutFrameForNode(aTo, aRv);
198
  if (fromFrame && toFrame) {
199
    if (!CheckFramesInSameTopLevelBrowsingContext(fromFrame, toFrame, aRv)) {
200
      return;
201
    }
202
    nsPoint fromOffset = GetBoxRectForFrame(&fromFrame, aOptions.mFromBox).TopLeft();
203
    nsPoint toOffset = GetBoxRectForFrame(&toFrame, aOptions.mToBox).TopLeft();
204
    gfxPoint fromOffsetGfx(nsPresContext::AppUnitsToFloatCSSPixels(fromOffset.x),
205
                           nsPresContext::AppUnitsToFloatCSSPixels(fromOffset.y));
206
    for (uint32_t i = 0; i < aPointCount; ++i) {
207
      aPoints[i] += fromOffsetGfx;
208
    }
209
    nsLayoutUtils::TransformResult rv =
210
      nsLayoutUtils::TransformCSSPoints(fromFrame, toFrame, aPointCount, aPoints);
211
    if (rv == nsLayoutUtils::TRANSFORM_SUCCEEDED) {
212
      gfxPoint toOffsetGfx(nsPresContext::AppUnitsToFloatCSSPixels(toOffset.x),
213
                           nsPresContext::AppUnitsToFloatCSSPixels(toOffset.y));
214
      for (uint32_t i = 0; i < aPointCount; ++i) {
215
        aPoints[i] -= toOffsetGfx;
216
      }
217
      return;
218
    }
219
  }
220
  for (uint32_t i = 0; i < aPointCount; ++i) {
221
    aPoints[i] = gfxPoint(0.0, 0.0);
222
  }
191
}
223
}
224
225
}
(-)a/layout/base/CoordinateTransformations.h (+9 lines)
Line     Link Here 
 Lines 16-33    Link Here 
16
 */
16
 */
17
17
18
class nsINode;
18
class nsINode;
19
19
20
namespace mozilla {
20
namespace mozilla {
21
21
22
namespace dom {
22
namespace dom {
23
struct BoxQuadOptions;
23
struct BoxQuadOptions;
24
struct ConvertPointOptions;
24
}
25
}
25
26
27
/**
28
 * Converts points from being relative to aTo to relative to aFrom, following
29
 * the rules for Node.convertPointFromNode. May set an error in aRv.
30
 */
31
void TransformCSSPoints(nsINode* aTo, nsINode* aFrom,
32
                        uint32_t aPointCount, gfxPoint* aPoints,
33
                        const dom::ConvertPointOptions& aOptions, ErrorResult& aRv);
34
26
struct Quad2D {
35
struct Quad2D {
27
  gfxPoint mPoints[4];
36
  gfxPoint mPoints[4];
28
};
37
};
29
/**
38
/**
30
 * Computes quads for aNode using aOptions, according to Node.getBoxQuads.
39
 * Computes quads for aNode using aOptions, according to Node.getBoxQuads.
31
 * May set an error in aRv.
40
 * May set an error in aRv.
32
 */
41
 */
33
void GetBoxQuads(nsINode* aNode,
42
void GetBoxQuads(nsINode* aNode,

Return to bug 918189