mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-06-25 20:29:33 +00:00
closes #520: Document.elementsFromPoint() M1164427
This commit is contained in:
parent
e5c93de89f
commit
7e7cdb504d
|
@ -3274,15 +3274,39 @@ nsIDocument::ElementFromPoint(float aX, float aY)
|
||||||
return ElementFromPointHelper(aX, aY, false, true);
|
return ElementFromPointHelper(aX, aY, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsIDocument::ElementsFromPoint(float aX, float aY,
|
||||||
|
nsTArray<RefPtr<Element>>& aElements)
|
||||||
|
{
|
||||||
|
ElementsFromPointHelper(aX, aY, nsIDocument::FLUSH_LAYOUT, aElements);
|
||||||
|
}
|
||||||
|
|
||||||
Element*
|
Element*
|
||||||
nsDocument::ElementFromPointHelper(float aX, float aY,
|
nsDocument::ElementFromPointHelper(float aX, float aY,
|
||||||
bool aIgnoreRootScrollFrame,
|
bool aIgnoreRootScrollFrame,
|
||||||
bool aFlushLayout)
|
bool aFlushLayout)
|
||||||
{
|
{
|
||||||
// As per the the spec, we return null if either coord is negative
|
nsAutoTArray<RefPtr<Element>, 1> elementArray;
|
||||||
if (!aIgnoreRootScrollFrame && (aX < 0 || aY < 0)) {
|
ElementsFromPointHelper(aX, aY,
|
||||||
|
((aIgnoreRootScrollFrame ? nsIDocument::IGNORE_ROOT_SCROLL_FRAME : 0) |
|
||||||
|
(aFlushLayout ? nsIDocument::FLUSH_LAYOUT : 0) |
|
||||||
|
nsIDocument::IS_ELEMENT_FROM_POINT),
|
||||||
|
elementArray);
|
||||||
|
if (elementArray.IsEmpty()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
return elementArray[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsDocument::ElementsFromPointHelper(float aX, float aY,
|
||||||
|
uint32_t aFlags,
|
||||||
|
nsTArray<RefPtr<mozilla::dom::Element>>& aElements)
|
||||||
|
{
|
||||||
|
// As per the the spec, we return null if either coord is negative
|
||||||
|
if (!(aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) && (aX < 0 || aY < 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
|
nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
|
||||||
nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
|
nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
|
||||||
|
@ -3290,32 +3314,58 @@ nsDocument::ElementFromPointHelper(float aX, float aY,
|
||||||
|
|
||||||
// Make sure the layout information we get is up-to-date, and
|
// Make sure the layout information we get is up-to-date, and
|
||||||
// ensure we get a root frame (for everything but XUL)
|
// ensure we get a root frame (for everything but XUL)
|
||||||
if (aFlushLayout)
|
if (aFlags & nsIDocument::FLUSH_LAYOUT) {
|
||||||
FlushPendingNotifications(Flush_Layout);
|
FlushPendingNotifications(Flush_Layout);
|
||||||
|
}
|
||||||
|
|
||||||
nsIPresShell *ps = GetShell();
|
nsIPresShell *ps = GetShell();
|
||||||
if (!ps) {
|
if (!ps) {
|
||||||
return nullptr;
|
return;
|
||||||
}
|
}
|
||||||
nsIFrame *rootFrame = ps->GetRootFrame();
|
nsIFrame *rootFrame = ps->GetRootFrame();
|
||||||
|
|
||||||
// XUL docs, unlike HTML, have no frame tree until everything's done loading
|
// XUL docs, unlike HTML, have no frame tree until everything's done loading
|
||||||
if (!rootFrame) {
|
if (!rootFrame) {
|
||||||
return nullptr; // return null to premature XUL callers as a reminder to wait
|
return; // return null to premature XUL callers as a reminder to wait
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame *ptFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, pt,
|
nsTArray<nsIFrame*> outFrames;
|
||||||
|
// Emulate what GetFrameAtPoint does, since we want all the frames under our
|
||||||
|
// point.
|
||||||
|
nsLayoutUtils::GetFramesForArea(rootFrame, nsRect(pt, nsSize(1, 1)), outFrames,
|
||||||
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC |
|
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC |
|
||||||
(aIgnoreRootScrollFrame ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
|
((aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
|
||||||
if (!ptFrame) {
|
|
||||||
return nullptr;
|
// Dunno when this would ever happen, as we should at least have a root frame under us?
|
||||||
|
if (outFrames.IsEmpty()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIContent* elem = GetContentInThisDocument(ptFrame);
|
// Used to filter out repeated elements in sequence.
|
||||||
if (elem && !elem->IsElement()) {
|
nsIContent* lastAdded = nullptr;
|
||||||
elem = elem->GetParent();
|
|
||||||
|
for (uint32_t i = 0; i < outFrames.Length(); i++) {
|
||||||
|
nsIContent* node = GetContentInThisDocument(outFrames[i]);
|
||||||
|
|
||||||
|
if (!node || !node->IsElement()) {
|
||||||
|
// If this helper is called via ElementsFromPoint, we need to make sure
|
||||||
|
// our frame is an element. Otherwise return whatever the top frame is
|
||||||
|
// even if it isn't the top-painted element.
|
||||||
|
if (!(aFlags & nsIDocument::IS_ELEMENT_FROM_POINT)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
node = node->GetParent();
|
||||||
|
}
|
||||||
|
if (node && node != lastAdded) {
|
||||||
|
aElements.AppendElement(node->AsElement());
|
||||||
|
lastAdded = node;
|
||||||
|
// If this helper is called via ElementFromPoint, just return the first
|
||||||
|
// element we find.
|
||||||
|
if (aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return elem ? elem->AsElement() : nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -1029,8 +1029,12 @@ public:
|
||||||
const nsAString& aAttrValue) const override;
|
const nsAString& aAttrValue) const override;
|
||||||
|
|
||||||
virtual Element* ElementFromPointHelper(float aX, float aY,
|
virtual Element* ElementFromPointHelper(float aX, float aY,
|
||||||
bool aIgnoreRootScrollFrame,
|
bool aIgnoreRootScrollFrame,
|
||||||
bool aFlushLayout) override;
|
bool aFlushLayout) override;
|
||||||
|
|
||||||
|
virtual void ElementsFromPointHelper(float aX, float aY,
|
||||||
|
uint32_t aFlags,
|
||||||
|
nsTArray<RefPtr<mozilla::dom::Element>>& aElements) override;
|
||||||
|
|
||||||
virtual nsresult NodesFromRectHelper(float aX, float aY,
|
virtual nsresult NodesFromRectHelper(float aX, float aY,
|
||||||
float aTopSize, float aRightSize,
|
float aTopSize, float aRightSize,
|
||||||
|
|
|
@ -1672,6 +1672,16 @@ public:
|
||||||
bool aIgnoreRootScrollFrame,
|
bool aIgnoreRootScrollFrame,
|
||||||
bool aFlushLayout) = 0;
|
bool aFlushLayout) = 0;
|
||||||
|
|
||||||
|
enum ElementsFromPointFlags {
|
||||||
|
IGNORE_ROOT_SCROLL_FRAME = 1,
|
||||||
|
FLUSH_LAYOUT = 2,
|
||||||
|
IS_ELEMENT_FROM_POINT = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void ElementsFromPointHelper(float aX, float aY,
|
||||||
|
uint32_t aFlags,
|
||||||
|
nsTArray<RefPtr<mozilla::dom::Element>>& aElements) = 0;
|
||||||
|
|
||||||
virtual nsresult NodesFromRectHelper(float aX, float aY,
|
virtual nsresult NodesFromRectHelper(float aX, float aY,
|
||||||
float aTopSize, float aRightSize,
|
float aTopSize, float aRightSize,
|
||||||
float aBottomSize, float aLeftSize,
|
float aBottomSize, float aLeftSize,
|
||||||
|
@ -2531,6 +2541,9 @@ public:
|
||||||
virtual mozilla::dom::DOMStringList* StyleSheetSets() = 0;
|
virtual mozilla::dom::DOMStringList* StyleSheetSets() = 0;
|
||||||
virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) = 0;
|
virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) = 0;
|
||||||
Element* ElementFromPoint(float aX, float aY);
|
Element* ElementFromPoint(float aX, float aY);
|
||||||
|
void ElementsFromPoint(float aX,
|
||||||
|
float aY,
|
||||||
|
nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the location of the caret position (DOM node and character
|
* Retrieve the location of the caret position (DOM node and character
|
||||||
|
|
|
@ -278,7 +278,7 @@ partial interface Document {
|
||||||
// http://dev.w3.org/csswg/cssom-view/#extensions-to-the-document-interface
|
// http://dev.w3.org/csswg/cssom-view/#extensions-to-the-document-interface
|
||||||
partial interface Document {
|
partial interface Document {
|
||||||
Element? elementFromPoint (float x, float y);
|
Element? elementFromPoint (float x, float y);
|
||||||
|
sequence<Element> elementsFromPoint (float x, float y);
|
||||||
CaretPosition? caretPositionFromPoint (float x, float y);
|
CaretPosition? caretPositionFromPoint (float x, float y);
|
||||||
|
|
||||||
readonly attribute Element? scrollingElement;
|
readonly attribute Element? scrollingElement;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user