Open Bug 1306634 Opened 3 years ago Updated 3 days ago

Long-pressing on an iframe which doesn't have focus puts selection in unexpected place


(Core :: DOM: Selection, defect)

51 Branch
Not set



Tracking Status
firefox49 --- wontfix
firefox50 --- fix-optional
firefox51 --- affected
firefox52 --- wontfix


(Reporter: kats, Assigned: TYLin)


(Blocks 1 open bug)



(3 files)

On Fennec, or Windows e10s with touch:

1. Load a page like which has an iframe
2. Tap outside the iframe to make sure the parent window has focus
3. Long-press inside the iframe (on some blank space) to bring up the text-selection carets

ER: text selection carets show up inside the iframe

AR: text selection carets show up outside the iframe

Note that in step 2 if you tap inside the iframe (on blank space) then the iframe gets focus and things work as expected. I believe what we need to do is give the iframe focus once we detect the long-press. Chrome seems to do this as well.
I thought this would be fixable by simply copying the code at [1] down into the eLongTap case, but that doesn't work.

After looking at the code some more I then thought that the problem was the AccessibleCaretEventHub schedules its internal long-tap injector when it receives the touchstart, but at that point the focus is still in the parent window. So the long-tap injector triggers a long-tap on the parent window, regardless of whether the focus changes later. But disabling the long-tap injector and using the eMouseLongTap event didn't fix the problem either. Still digging...

I think it might be related to how the EventHub is delivered events from nsPresShell. It looks like it always sends it from the focused presShell, or the top-level presShell. In this case we want it to go to the presShell that's under the finger which is only computed later in the code. I haven't yet confirmed.
Attached patch HackSplinter Review
Indeed, that is the problem. A patch like the one attached, which passes positioned events to the AccessibleCaretEventHub of the presshell *after* hit-testing fixes this bug. It probably breaks other things, though. I'm not sure what the correct mechanism here is to fix this.
Unassigning since I'm not familiar enough with the intricacies of the AccessibleCaret event delivery timing to really tackle this.
Assignee: bugmail → nobody
On Windows this will affect 52 and up, but on Fennec it is already in release (48 and up).
OS: Unspecified → Android
Hardware: Unspecified → All
Duplicate of this bug: 1257273
I feel the patch in comment 3 makes some sense. However, after applying the patch, sometimes I cannot drag caret. 

Each PresShell owns an EventHub, and we should want to let the event hub under the finger to handle the event.  The event retargeting code [1] was from the very first implementation in bug 924692.  Morris, do you recall why we did [1]?

Flags: needinfo?(mtseng)
That because we want to active only one caret at the same time. Otherwise it might have multiple caret appeared on the screen.
Flags: needinfo?(mtseng)
Mass wontfix for bugs affecting firefox 52.
Assignee: nobody → aethanyc
Duplicate of this bug: 1199967

Long-pressing on a text in an unfocused iframe to select a word never
works. Currently, you need to single tap to focus the iframe first.

Each PresShell has an associated AccessibleCaretEventHub. This patch
fixes this bug by routing the event to the AccessibleCaretEventHub under
the event point, and handle it there. If the event is not handled, then
we handle it by the focused AccessibleCaretEventHub as before.

I've experimented with only routing the event to the
AccessibleCaretEventHub under the event point, without routing to the
fallback focused AccessibleCaretEventHub. However, caret dragging didn't
work in iframes. I didn't debug further.

Consider the following scenario:

  1. Select a word in an iframe.
  2. Select a word in the parent document. (The carets in iframe hide
    due to blur, but the selection is still there.)
  3. Scroll the parent document.

The selection in the iframe (made in step 1) has a non-collapsed range.
Thus the carets show again after scrolling due to UpdateCarets()
called in the end of AccessibleCaretManager::OnScrollEnd().

To fix the dual AccessibleCaret in the same page (described in bug
1199967), we can simply show no carets if the window is not focused.
This behavior always matches Google Chrome on Android.

Depends on D52767

You need to log in before you can comment on or make changes to this bug.