mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1188185 - Zoomed View appears when the two links are the same link. r=kats
This commit is contained in:
parent
df305143e3
commit
30f7490d25
@ -34,7 +34,7 @@ namespace mozilla {
|
||||
* designing for touch events will take their own steps to account for
|
||||
* inaccurate touch events.
|
||||
*
|
||||
* IsElementClickable() encapsulates the heuristic that determines whether an
|
||||
* GetClickableAncestor() encapsulates the heuristic that determines whether an
|
||||
* element is expected to respond to mouse events. An element is deemed
|
||||
* "clickable" if it has registered listeners for "click", "mousedown" or
|
||||
* "mouseup", or is on a whitelist of element tags (<a>, <button>, <input>,
|
||||
@ -48,7 +48,7 @@ namespace mozilla {
|
||||
* event radii are disabled), we always use that element. Otherwise we collect
|
||||
* all frames intersecting a rectangle around the event position (taking CSS
|
||||
* transforms into account) and choose the best candidate in GetClosest().
|
||||
* Only IsElementClickable() candidates are considered; if none are found,
|
||||
* Only GetClickableAncestor() candidates are considered; if none are found,
|
||||
* then we revert to targeting the element under the event position.
|
||||
* We ignore candidates outside the document subtree rooted by the
|
||||
* document of the element directly under the event position. This ensures that
|
||||
@ -187,8 +187,8 @@ IsDescendant(nsIFrame* aFrame, nsIContent* aAncestor, nsAutoString* aLabelTarget
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsElementClickable(nsIFrame* aFrame, nsIAtom* stopAt = nullptr, nsAutoString* aLabelTargetId = nullptr)
|
||||
static nsIContent*
|
||||
GetClickableAncestor(nsIFrame* aFrame, nsIAtom* stopAt = nullptr, nsAutoString* aLabelTargetId = nullptr)
|
||||
{
|
||||
// Input events propagate up the content tree so we'll follow the content
|
||||
// ancestors to look for elements accepting the click.
|
||||
@ -198,19 +198,19 @@ IsElementClickable(nsIFrame* aFrame, nsIAtom* stopAt = nullptr, nsAutoString* aL
|
||||
break;
|
||||
}
|
||||
if (HasTouchListener(content) || HasMouseListener(content)) {
|
||||
return true;
|
||||
return content;
|
||||
}
|
||||
if (content->IsAnyOfHTMLElements(nsGkAtoms::button,
|
||||
nsGkAtoms::input,
|
||||
nsGkAtoms::select,
|
||||
nsGkAtoms::textarea)) {
|
||||
return true;
|
||||
return content;
|
||||
}
|
||||
if (content->IsHTMLElement(nsGkAtoms::label)) {
|
||||
if (aLabelTargetId) {
|
||||
content->GetAttr(kNameSpaceID_None, nsGkAtoms::_for, *aLabelTargetId);
|
||||
}
|
||||
return true;
|
||||
return content;
|
||||
}
|
||||
|
||||
// Bug 921928: we don't have access to the content of remote iframe.
|
||||
@ -221,7 +221,7 @@ IsElementClickable(nsIFrame* aFrame, nsIAtom* stopAt = nullptr, nsAutoString* aL
|
||||
nsGkAtoms::_true, eIgnoreCase) &&
|
||||
content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::Remote,
|
||||
nsGkAtoms::_true, eIgnoreCase)) {
|
||||
return true;
|
||||
return content;
|
||||
}
|
||||
|
||||
// See nsCSSFrameConstructor::FindXULTagData. This code is not
|
||||
@ -236,24 +236,24 @@ IsElementClickable(nsIFrame* aFrame, nsIAtom* stopAt = nullptr, nsAutoString* aL
|
||||
nsGkAtoms::menulist,
|
||||
nsGkAtoms::scrollbarbutton,
|
||||
nsGkAtoms::resizer)) {
|
||||
return true;
|
||||
return content;
|
||||
}
|
||||
|
||||
static nsIContent::AttrValuesArray clickableRoles[] =
|
||||
{ &nsGkAtoms::button, &nsGkAtoms::key, nullptr };
|
||||
if (content->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::role,
|
||||
clickableRoles, eIgnoreCase) >= 0) {
|
||||
return true;
|
||||
return content;
|
||||
}
|
||||
if (content->IsEditable()) {
|
||||
return true;
|
||||
return content;
|
||||
}
|
||||
nsCOMPtr<nsIURI> linkURI;
|
||||
if (content->IsLink(getter_AddRefs(linkURI))) {
|
||||
return true;
|
||||
return content;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static nscoord
|
||||
@ -362,6 +362,7 @@ GetClosest(nsIFrame* aRoot, const nsPoint& aPointRelativeToRootFrame,
|
||||
nsIFrame* aRestrictToDescendants, nsIContent* aClickableAncestor,
|
||||
nsTArray<nsIFrame*>& aCandidates, int32_t* aElementsInCluster)
|
||||
{
|
||||
std::vector<nsIContent*> mContentsInCluster; // List of content elements in the cluster without duplicate
|
||||
nsIFrame* bestTarget = nullptr;
|
||||
// Lower is better; distance is in appunits
|
||||
float bestDistance = 1e6f;
|
||||
@ -375,7 +376,6 @@ GetClosest(nsIFrame* aRoot, const nsPoint& aPointRelativeToRootFrame,
|
||||
nsRect(nsPoint(0, 0), f->GetSize()), aRoot, &preservesAxisAlignedRectangles);
|
||||
nsRegion region;
|
||||
region.And(exposedRegion, borderBox);
|
||||
|
||||
if (region.IsEmpty()) {
|
||||
PET_LOG(" candidate %p had empty hit region\n", f);
|
||||
continue;
|
||||
@ -388,12 +388,13 @@ GetClosest(nsIFrame* aRoot, const nsPoint& aPointRelativeToRootFrame,
|
||||
}
|
||||
|
||||
nsAutoString labelTargetId;
|
||||
if (aClickableAncestor) {
|
||||
if (!IsDescendant(f, aClickableAncestor, &labelTargetId)) {
|
||||
PET_LOG(" candidate %p is not a descendant of required ancestor\n", f);
|
||||
continue;
|
||||
}
|
||||
} else if (!IsElementClickable(f, nsGkAtoms::body, &labelTargetId)) {
|
||||
if (aClickableAncestor && !IsDescendant(f, aClickableAncestor, &labelTargetId)) {
|
||||
PET_LOG(" candidate %p is not a descendant of required ancestor\n", f);
|
||||
continue;
|
||||
}
|
||||
|
||||
nsIContent* clickableContent = GetClickableAncestor(f, nsGkAtoms::body, &labelTargetId);
|
||||
if (!aClickableAncestor && !clickableContent) {
|
||||
PET_LOG(" candidate %p was not clickable\n", f);
|
||||
continue;
|
||||
}
|
||||
@ -403,7 +404,7 @@ GetClosest(nsIFrame* aRoot, const nsPoint& aPointRelativeToRootFrame,
|
||||
PET_LOG(" candidate %p was ancestor for bestTarget %p\n", f, bestTarget);
|
||||
continue;
|
||||
}
|
||||
if (!nsLayoutUtils::IsAncestorFrameCrossDoc(aRestrictToDescendants, f, aRoot)) {
|
||||
if (!aClickableAncestor && !nsLayoutUtils::IsAncestorFrameCrossDoc(aRestrictToDescendants, f, aRoot)) {
|
||||
PET_LOG(" candidate %p was not descendant of restrictroot %p\n", f, aRestrictToDescendants);
|
||||
continue;
|
||||
}
|
||||
@ -413,7 +414,9 @@ GetClosest(nsIFrame* aRoot, const nsPoint& aPointRelativeToRootFrame,
|
||||
// If this element is present in the current list, do not count the frame in
|
||||
// the cluster elements counter
|
||||
if (labelTargetId.IsEmpty() || !IsElementPresent(aCandidates, labelTargetId)) {
|
||||
(*aElementsInCluster)++;
|
||||
if (std::find(mContentsInCluster.begin(), mContentsInCluster.end(), clickableContent) == mContentsInCluster.end()) {
|
||||
mContentsInCluster.push_back(clickableContent);
|
||||
}
|
||||
}
|
||||
|
||||
// distance is in appunits
|
||||
@ -430,6 +433,7 @@ GetClosest(nsIFrame* aRoot, const nsPoint& aPointRelativeToRootFrame,
|
||||
bestTarget = f;
|
||||
}
|
||||
}
|
||||
*aElementsInCluster = mContentsInCluster.size();
|
||||
return bestTarget;
|
||||
}
|
||||
|
||||
@ -524,12 +528,14 @@ FindFrameTargetedByInputEvent(WidgetGUIEvent* aEvent,
|
||||
return target;
|
||||
}
|
||||
nsIContent* clickableAncestor = nullptr;
|
||||
if (target && IsElementClickable(target, nsGkAtoms::body)) {
|
||||
if (!IsElementClickableAndReadable(target, aEvent, prefs)) {
|
||||
aEvent->AsMouseEventBase()->hitCluster = true;
|
||||
if (target) {
|
||||
clickableAncestor = GetClickableAncestor(target, nsGkAtoms::body);
|
||||
if (clickableAncestor) {
|
||||
if (!IsElementClickableAndReadable(target, aEvent, prefs)) {
|
||||
aEvent->AsMouseEventBase()->hitCluster = true;
|
||||
}
|
||||
PET_LOG("Target %p is clickable\n", target);
|
||||
}
|
||||
PET_LOG("Target %p is clickable\n", target);
|
||||
clickableAncestor = target->GetContent();
|
||||
}
|
||||
|
||||
// Do not modify targeting for actual mouse hardware; only for mouse
|
||||
@ -544,7 +550,7 @@ FindFrameTargetedByInputEvent(WidgetGUIEvent* aEvent,
|
||||
|
||||
// If the exact target is non-null, only consider candidate targets in the same
|
||||
// document as the exact target. Otherwise, if an ancestor document has
|
||||
// a mouse event handler for example, targets that are !IsElementClickable can
|
||||
// a mouse event handler for example, targets that are !GetClickableAncestor can
|
||||
// never be targeted --- something nsSubDocumentFrame in an ancestor document
|
||||
// would be targeted instead.
|
||||
nsIFrame* restrictToDescendants = target ?
|
||||
|
Loading…
Reference in New Issue
Block a user