mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-12-29 02:31:05 +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);
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::ElementsFromPoint(float aX, float aY,
|
||||
nsTArray<RefPtr<Element>>& aElements)
|
||||
{
|
||||
ElementsFromPointHelper(aX, aY, nsIDocument::FLUSH_LAYOUT, aElements);
|
||||
}
|
||||
|
||||
Element*
|
||||
nsDocument::ElementFromPointHelper(float aX, float aY,
|
||||
bool aIgnoreRootScrollFrame,
|
||||
bool aFlushLayout)
|
||||
{
|
||||
// As per the the spec, we return null if either coord is negative
|
||||
if (!aIgnoreRootScrollFrame && (aX < 0 || aY < 0)) {
|
||||
nsAutoTArray<RefPtr<Element>, 1> elementArray;
|
||||
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 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 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
|
||||
// ensure we get a root frame (for everything but XUL)
|
||||
if (aFlushLayout)
|
||||
if (aFlags & nsIDocument::FLUSH_LAYOUT) {
|
||||
FlushPendingNotifications(Flush_Layout);
|
||||
}
|
||||
|
||||
nsIPresShell *ps = GetShell();
|
||||
if (!ps) {
|
||||
return nullptr;
|
||||
return;
|
||||
}
|
||||
nsIFrame *rootFrame = ps->GetRootFrame();
|
||||
|
||||
// XUL docs, unlike HTML, have no frame tree until everything's done loading
|
||||
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 |
|
||||
(aIgnoreRootScrollFrame ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
|
||||
if (!ptFrame) {
|
||||
return nullptr;
|
||||
((aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
|
||||
|
||||
// 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);
|
||||
if (elem && !elem->IsElement()) {
|
||||
elem = elem->GetParent();
|
||||
// Used to filter out repeated elements in sequence.
|
||||
nsIContent* lastAdded = nullptr;
|
||||
|
||||
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
|
||||
|
@ -1029,8 +1029,12 @@ public:
|
||||
const nsAString& aAttrValue) const override;
|
||||
|
||||
virtual Element* ElementFromPointHelper(float aX, float aY,
|
||||
bool aIgnoreRootScrollFrame,
|
||||
bool aFlushLayout) override;
|
||||
bool aIgnoreRootScrollFrame,
|
||||
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,
|
||||
float aTopSize, float aRightSize,
|
||||
|
@ -1672,6 +1672,16 @@ public:
|
||||
bool aIgnoreRootScrollFrame,
|
||||
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,
|
||||
float aTopSize, float aRightSize,
|
||||
float aBottomSize, float aLeftSize,
|
||||
@ -2531,6 +2541,9 @@ public:
|
||||
virtual mozilla::dom::DOMStringList* StyleSheetSets() = 0;
|
||||
virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) = 0;
|
||||
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
|
||||
|
@ -278,7 +278,7 @@ partial interface Document {
|
||||
// http://dev.w3.org/csswg/cssom-view/#extensions-to-the-document-interface
|
||||
partial interface Document {
|
||||
Element? elementFromPoint (float x, float y);
|
||||
|
||||
sequence<Element> elementsFromPoint (float x, float y);
|
||||
CaretPosition? caretPositionFromPoint (float x, float y);
|
||||
|
||||
readonly attribute Element? scrollingElement;
|
||||
|
Loading…
Reference in New Issue
Block a user