зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1306634 Part 1 - Handle a long press to select a word in an unfocused iframe. r=mats,marionette-reviewers,whimboo
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. Differential Revision: https://phabricator.services.mozilla.com/D52767 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
5a611b020b
Коммит
2e68f8780b
|
@ -6459,7 +6459,8 @@ nsresult PresShell::EventHandler::HandleEvent(nsIFrame* aFrameForPresShell,
|
|||
|
||||
mPresShell->RecordMouseLocation(aGUIEvent);
|
||||
|
||||
if (MaybeHandleEventWithAccessibleCaret(aGUIEvent, aEventStatus)) {
|
||||
if (MaybeHandleEventWithAccessibleCaret(aFrameForPresShell, aGUIEvent,
|
||||
aEventStatus)) {
|
||||
// Probably handled by AccessibleCaretEventHub.
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -6870,7 +6871,8 @@ bool PresShell::EventHandler::DispatchPrecedingPointerEvent(
|
|||
}
|
||||
|
||||
bool PresShell::EventHandler::MaybeHandleEventWithAccessibleCaret(
|
||||
WidgetGUIEvent* aGUIEvent, nsEventStatus* aEventStatus) {
|
||||
nsIFrame* aFrameForPresShell, WidgetGUIEvent* aGUIEvent,
|
||||
nsEventStatus* aEventStatus) {
|
||||
MOZ_ASSERT(aGUIEvent);
|
||||
MOZ_ASSERT(aEventStatus);
|
||||
|
||||
|
@ -6886,8 +6888,37 @@ bool PresShell::EventHandler::MaybeHandleEventWithAccessibleCaret(
|
|||
return false;
|
||||
}
|
||||
|
||||
// We have to target the focus window because regardless of where the
|
||||
// touch goes, we want to access the copy paste manager.
|
||||
// First, try the event hub at the event point to handle a long press to
|
||||
// select a word in an unfocused window.
|
||||
do {
|
||||
EventTargetData eventTargetData(nullptr);
|
||||
if (!ComputeEventTargetFrameAndPresShellAtEventPoint(
|
||||
aFrameForPresShell, aGUIEvent, &eventTargetData)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!eventTargetData.mPresShell) {
|
||||
break;
|
||||
}
|
||||
|
||||
RefPtr<AccessibleCaretEventHub> eventHub =
|
||||
eventTargetData.mPresShell->GetAccessibleCaretEventHub();
|
||||
if (!eventHub) {
|
||||
break;
|
||||
}
|
||||
|
||||
*aEventStatus = eventHub->HandleEvent(aGUIEvent);
|
||||
if (*aEventStatus != nsEventStatus_eConsumeNoDefault) {
|
||||
break;
|
||||
}
|
||||
|
||||
// If the event is consumed, cancel APZC panning by setting
|
||||
// mMultipleActionsPrevented.
|
||||
aGUIEvent->mFlags.mMultipleActionsPrevented = true;
|
||||
return true;
|
||||
} while (false);
|
||||
|
||||
// Then, we target the event to the event hub at the focused window.
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = GetFocusedDOMWindowInOurWindow();
|
||||
if (!window) {
|
||||
return false;
|
||||
|
|
|
@ -2292,13 +2292,16 @@ class PresShell final : public nsStubDocumentObserver,
|
|||
* MaybeHandleEventWithAccessibleCaret() may handle aGUIEvent with
|
||||
* AccessibleCaretEventHub if it's necessary.
|
||||
*
|
||||
* @param aFrameForPresShell The frame for PresShell. See explanation of
|
||||
* HandleEvent() for the details.
|
||||
* @param aGUIEvent Event may be handled by AccessibleCaretEventHub.
|
||||
* @param aEventStatus [in/out] EventStatus of aGUIEvent.
|
||||
* @return true if AccessibleCaretEventHub handled the
|
||||
* event and caller shouldn't keep handling it.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
bool MaybeHandleEventWithAccessibleCaret(WidgetGUIEvent* aGUIEvent,
|
||||
bool MaybeHandleEventWithAccessibleCaret(nsIFrame* aFrameForPresShell,
|
||||
WidgetGUIEvent* aGUIEvent,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
/**
|
||||
|
|
|
@ -520,6 +520,28 @@ class AccessibleCaretSelectionModeTestCase(MarionetteTestCase):
|
|||
|
||||
self.assertNotEqual(self.to_unix_line_ending(sel.selected_content), '')
|
||||
|
||||
def test_select_word_inside_an_unfocused_iframe(self):
|
||||
'''Bug 1306634: Test we can long press to select a word in an unfocused iframe.'''
|
||||
self.open_test_html(self._iframe_html)
|
||||
|
||||
el = self.marionette.find_element(By.ID, self._input_id)
|
||||
sel = SelectionManager(el)
|
||||
|
||||
# First, we select the first word in the input of the parent document.
|
||||
el_first_word = sel.content.split()[0] # first world is "ABC"
|
||||
self.long_press_on_word(el, 0)
|
||||
self.assertEqual(el_first_word, sel.selected_content)
|
||||
|
||||
# Then, we long press on the center of the iframe. It should select a
|
||||
# word inside of the document, not the placehoder in the parent
|
||||
# document.
|
||||
iframe = self.marionette.find_element(By.ID, 'frame')
|
||||
self.long_press_on_location(iframe)
|
||||
self.marionette.switch_to_frame(iframe)
|
||||
body = self.marionette.find_element(By.ID, 'bd')
|
||||
sel = SelectionManager(body)
|
||||
self.assertNotEqual('', sel.selected_content)
|
||||
|
||||
def test_carets_initialized_in_display_none(self):
|
||||
'''Test AccessibleCaretEventHub is properly initialized on a <html> with
|
||||
display: none.
|
||||
|
|
|
@ -9,12 +9,7 @@
|
|||
<title>Marionette tests for AccessibleCaret in selection mode (iframe)</title>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
*
|
||||
{
|
||||
-moz-user-select:none;
|
||||
}
|
||||
</style>
|
||||
<iframe id="frame" src="test_carets_longtext.html" style="width: 10em; height: 8em;"></iframe>
|
||||
<input id="input" value="ABC DEF GHI">
|
||||
</body>
|
||||
</html>
|
||||
|
|
Загрузка…
Ссылка в новой задаче