More web optimizations.
This commit is contained in:
@@ -173,8 +173,12 @@ class Script(default.Script):
|
|||||||
obj,
|
obj,
|
||||||
offset,
|
offset,
|
||||||
focusOverride=None,
|
focusOverride=None,
|
||||||
):
|
isCaretSelection: bool | None = None,
|
||||||
if not self.utilities.lastInputEventWasCaretNavWithSelection():
|
) -> bool:
|
||||||
|
if isCaretSelection is None:
|
||||||
|
isCaretSelection = self.utilities.lastInputEventWasCaretNavWithSelection()
|
||||||
|
|
||||||
|
if not isCaretSelection:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if focusOverride is not None:
|
if focusOverride is not None:
|
||||||
@@ -3181,6 +3185,8 @@ class Script(default.Script):
|
|||||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
reason = AXUtilitiesEvent.get_text_event_reason(event)
|
||||||
|
|
||||||
if not self.utilities.inDocumentContent(cthulhu_state.locusOfFocus):
|
if not self.utilities.inDocumentContent(cthulhu_state.locusOfFocus):
|
||||||
tokens = ["WEB: Event ignored: locusOfFocus", cthulhu_state.locusOfFocus,
|
tokens = ["WEB: Event ignored: locusOfFocus", cthulhu_state.locusOfFocus,
|
||||||
"is not in document content"]
|
"is not in document content"]
|
||||||
@@ -3208,8 +3214,18 @@ class Script(default.Script):
|
|||||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if self.utilities.lastInputEventWasCaretNavWithSelection() \
|
selectionReasons = (
|
||||||
and not AXText.get_selected_ranges(event.source):
|
TextEventReason.SELECTION_BY_CHARACTER,
|
||||||
|
TextEventReason.SELECTION_BY_LINE,
|
||||||
|
TextEventReason.SELECTION_BY_PARAGRAPH,
|
||||||
|
TextEventReason.SELECTION_BY_PAGE,
|
||||||
|
TextEventReason.SELECTION_BY_WORD,
|
||||||
|
TextEventReason.SELECTION_TO_FILE_BOUNDARY,
|
||||||
|
TextEventReason.SELECTION_TO_LINE_BOUNDARY,
|
||||||
|
TextEventReason.UNSPECIFIED_SELECTION,
|
||||||
|
)
|
||||||
|
isSelectionReason = reason in selectionReasons
|
||||||
|
if isSelectionReason and not AXText.get_selected_ranges(event.source):
|
||||||
document = self.utilities.getTopLevelDocumentForObject(event.source)
|
document = self.utilities.getTopLevelDocumentForObject(event.source)
|
||||||
obj, offset = self.utilities.getCaretContext(document, False, False)
|
obj, offset = self.utilities.getCaretContext(document, False, False)
|
||||||
focusOffset = AXText.get_caret_offset(event.source)
|
focusOffset = AXText.get_caret_offset(event.source)
|
||||||
@@ -3219,6 +3235,7 @@ class Script(default.Script):
|
|||||||
obj,
|
obj,
|
||||||
offset,
|
offset,
|
||||||
focusOverride=(event.source, focusOffset),
|
focusOverride=(event.source, focusOffset),
|
||||||
|
isCaretSelection=True,
|
||||||
):
|
):
|
||||||
msg = "WEB: Event handled: synthetic selection from event source"
|
msg = "WEB: Event handled: synthetic selection from event source"
|
||||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||||
@@ -3239,7 +3256,7 @@ class Script(default.Script):
|
|||||||
offset = AXText.get_caret_offset(event.source)
|
offset = AXText.get_caret_offset(event.source)
|
||||||
char = AXText.get_substring(event.source, offset, offset + 1)
|
char = AXText.get_substring(event.source, offset, offset + 1)
|
||||||
if char == self.EMBEDDED_OBJECT_CHARACTER \
|
if char == self.EMBEDDED_OBJECT_CHARACTER \
|
||||||
and not self.utilities.lastInputEventWasCaretNavWithSelection() \
|
and not isSelectionReason \
|
||||||
and not self.utilities.lastInputEventWasCommand():
|
and not self.utilities.lastInputEventWasCommand():
|
||||||
msg = "WEB: Ignoring: Not selecting and event offset is at embedded object"
|
msg = "WEB: Ignoring: Not selecting and event offset is at embedded object"
|
||||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||||
|
|||||||
@@ -529,11 +529,63 @@ class TextEventReasonRegressionTests(unittest.TestCase):
|
|||||||
"last_event_was_middle_release",
|
"last_event_was_middle_release",
|
||||||
"last_event_was_up_or_down",
|
"last_event_was_up_or_down",
|
||||||
"last_event_was_page_up_or_page_down",
|
"last_event_was_page_up_or_page_down",
|
||||||
|
"last_event_was_caret_selection",
|
||||||
|
"last_event_was_caret_navigation",
|
||||||
|
"last_event_was_line_navigation",
|
||||||
|
"last_event_was_word_navigation",
|
||||||
|
"last_event_was_character_navigation",
|
||||||
|
"last_event_was_page_navigation",
|
||||||
|
"last_event_was_line_boundary_navigation",
|
||||||
|
"last_event_was_file_boundary_navigation",
|
||||||
|
"last_event_was_select_all",
|
||||||
|
"last_event_was_primary_click_or_release",
|
||||||
)
|
)
|
||||||
for method in methods:
|
for method in methods:
|
||||||
getattr(manager, method).return_value = False
|
getattr(manager, method).return_value = False
|
||||||
return manager
|
return manager
|
||||||
|
|
||||||
|
def _classify_selection(
|
||||||
|
self,
|
||||||
|
event,
|
||||||
|
manager,
|
||||||
|
*,
|
||||||
|
focus=None,
|
||||||
|
focusIsSearch=False,
|
||||||
|
isEditable=False,
|
||||||
|
spinAncestor=None,
|
||||||
|
):
|
||||||
|
with (
|
||||||
|
mock.patch("cthulhu.input_event_manager.get_manager", return_value=manager),
|
||||||
|
mock.patch(
|
||||||
|
"cthulhu.ax_utilities_event.focus_manager.get_manager"
|
||||||
|
) as getFocusManager,
|
||||||
|
mock.patch(
|
||||||
|
"cthulhu.ax_utilities_event.AXUtilitiesRole.is_text_input_search",
|
||||||
|
return_value=focusIsSearch,
|
||||||
|
),
|
||||||
|
mock.patch(
|
||||||
|
"cthulhu.ax_utilities_event.AXUtilitiesState.is_editable",
|
||||||
|
return_value=isEditable,
|
||||||
|
),
|
||||||
|
mock.patch(
|
||||||
|
"cthulhu.ax_utilities_event.AXUtilitiesRole.is_terminal",
|
||||||
|
return_value=False,
|
||||||
|
),
|
||||||
|
mock.patch(
|
||||||
|
"cthulhu.ax_utilities_event.AXUtilitiesRole.is_spin_button",
|
||||||
|
return_value=False,
|
||||||
|
),
|
||||||
|
mock.patch.object(
|
||||||
|
web_script.AXObject,
|
||||||
|
"find_ancestor",
|
||||||
|
return_value=spinAncestor,
|
||||||
|
),
|
||||||
|
):
|
||||||
|
getFocusManager.return_value.get_locus_of_focus.return_value = (
|
||||||
|
event.source if focus is None else focus
|
||||||
|
)
|
||||||
|
return AXUtilitiesEvent._get_text_selection_changed_event_reason(event)
|
||||||
|
|
||||||
def _classify_insertion(
|
def _classify_insertion(
|
||||||
self,
|
self,
|
||||||
event,
|
event,
|
||||||
@@ -764,6 +816,92 @@ class TextEventReasonRegressionTests(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(reason, expected)
|
self.assertEqual(reason, expected)
|
||||||
|
|
||||||
|
def test_selection_classifier_covers_handler_reason_families(self):
|
||||||
|
source = object()
|
||||||
|
cases = (
|
||||||
|
(
|
||||||
|
"search presentable",
|
||||||
|
TextEventReason.SEARCH_PRESENTABLE,
|
||||||
|
{"focus": object(), "focusIsSearch": True},
|
||||||
|
{},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"search unpresentable",
|
||||||
|
TextEventReason.SEARCH_UNPRESENTABLE,
|
||||||
|
{"focus": object(), "focusIsSearch": True},
|
||||||
|
{"last_event_was_backspace": True},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"selection by word",
|
||||||
|
TextEventReason.SELECTION_BY_WORD,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
"last_event_was_caret_selection": True,
|
||||||
|
"last_event_was_word_navigation": True,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unspecified selection",
|
||||||
|
TextEventReason.UNSPECIFIED_SELECTION,
|
||||||
|
{},
|
||||||
|
{"last_event_was_caret_selection": True},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"navigation by character",
|
||||||
|
TextEventReason.NAVIGATION_BY_CHARACTER,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
"last_event_was_caret_navigation": True,
|
||||||
|
"last_event_was_character_navigation": True,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"select all",
|
||||||
|
TextEventReason.SELECT_ALL,
|
||||||
|
{},
|
||||||
|
{"last_event_was_select_all": True},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"primary mouse",
|
||||||
|
TextEventReason.MOUSE_PRIMARY_BUTTON,
|
||||||
|
{},
|
||||||
|
{"last_event_was_primary_click_or_release": True},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"typing",
|
||||||
|
TextEventReason.TYPING,
|
||||||
|
{"isEditable": True},
|
||||||
|
{"last_event_was_printable_key": True},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"editing command",
|
||||||
|
TextEventReason.PASTE,
|
||||||
|
{"isEditable": True},
|
||||||
|
{"last_event_was_paste": True},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"spin button",
|
||||||
|
TextEventReason.SPIN_BUTTON_VALUE_CHANGE,
|
||||||
|
{"isEditable": True, "spinAncestor": object()},
|
||||||
|
{"last_event_was_up_or_down": True},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
for name, expected, classifierKwargs, managerResults in cases:
|
||||||
|
with self.subTest(name=name):
|
||||||
|
manager = self._make_input_manager()
|
||||||
|
for method, result in managerResults.items():
|
||||||
|
getattr(manager, method).return_value = result
|
||||||
|
event = mock.Mock(type="object:text-selection-changed", source=source)
|
||||||
|
|
||||||
|
reason = self._classify_selection(
|
||||||
|
event,
|
||||||
|
manager,
|
||||||
|
**classifierKwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(reason, expected)
|
||||||
|
|
||||||
def test_tab_is_classified_as_focus_change_before_editable_state(self):
|
def test_tab_is_classified_as_focus_change_before_editable_state(self):
|
||||||
oldFocus = object()
|
oldFocus = object()
|
||||||
source = object()
|
source = object()
|
||||||
@@ -1727,6 +1865,11 @@ class WebSelectionRegressionTests(unittest.TestCase):
|
|||||||
|
|
||||||
with (
|
with (
|
||||||
mock.patch.object(web_script.cthulhu_state, "locusOfFocus", anchor),
|
mock.patch.object(web_script.cthulhu_state, "locusOfFocus", anchor),
|
||||||
|
mock.patch.object(
|
||||||
|
web_script.AXUtilitiesEvent,
|
||||||
|
"get_text_event_reason",
|
||||||
|
return_value=TextEventReason.SELECTION_BY_CHARACTER,
|
||||||
|
),
|
||||||
mock.patch.object(web_script.AXText, "get_caret_offset", return_value=0),
|
mock.patch.object(web_script.AXText, "get_caret_offset", return_value=0),
|
||||||
mock.patch.object(web_script.AXText, "get_selected_ranges", return_value=[]),
|
mock.patch.object(web_script.AXText, "get_selected_ranges", return_value=[]),
|
||||||
mock.patch.object(web_script.AXText, "get_substring", return_value="S"),
|
mock.patch.object(web_script.AXText, "get_substring", return_value="S"),
|
||||||
@@ -1744,6 +1887,214 @@ class WebSelectionRegressionTests(unittest.TestCase):
|
|||||||
"S",
|
"S",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_selection_reason_owns_synthetic_selection_recovery(self):
|
||||||
|
testScript = self._make_script()
|
||||||
|
event = mock.Mock(source=object())
|
||||||
|
testScript.utilities.textEventIsForNonNavigableTextObject.return_value = False
|
||||||
|
testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = False
|
||||||
|
testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = False
|
||||||
|
testScript._presentSyntheticCaretSelection = mock.Mock(return_value=True)
|
||||||
|
testScript.utilities.getTopLevelDocumentForObject.return_value = object()
|
||||||
|
testScript.utilities.getCaretContext.return_value = (object(), 0)
|
||||||
|
|
||||||
|
with (
|
||||||
|
mock.patch.object(web_script.cthulhu_state, "locusOfFocus", object()),
|
||||||
|
mock.patch.object(
|
||||||
|
web_script.AXUtilitiesEvent,
|
||||||
|
"get_text_event_reason",
|
||||||
|
return_value=TextEventReason.SELECTION_BY_CHARACTER,
|
||||||
|
) as getReason,
|
||||||
|
mock.patch.object(web_script.AXText, "get_selected_ranges", return_value=[]),
|
||||||
|
mock.patch.object(web_script.AXText, "get_caret_offset", return_value=0),
|
||||||
|
mock.patch.object(web_script.AXText, "get_substring", return_value="x"),
|
||||||
|
mock.patch.object(web_script.AXUtilities, "is_text_input", return_value=False),
|
||||||
|
):
|
||||||
|
result = web_script.Script.onTextSelectionChanged(testScript, event)
|
||||||
|
|
||||||
|
self.assertTrue(result)
|
||||||
|
getReason.assert_called_once_with(event)
|
||||||
|
testScript._presentSyntheticCaretSelection.assert_called_once()
|
||||||
|
|
||||||
|
def test_navigation_reason_does_not_claim_synthetic_selection_recovery(self):
|
||||||
|
testScript = self._make_script()
|
||||||
|
event = mock.Mock(source=object())
|
||||||
|
testScript.utilities.textEventIsForNonNavigableTextObject.return_value = False
|
||||||
|
testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = True
|
||||||
|
testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = False
|
||||||
|
testScript._presentSyntheticCaretSelection = mock.Mock(return_value=True)
|
||||||
|
testScript.utilities.getTopLevelDocumentForObject.return_value = object()
|
||||||
|
testScript.utilities.getCaretContext.return_value = (object(), 0)
|
||||||
|
|
||||||
|
with (
|
||||||
|
mock.patch.object(web_script.cthulhu_state, "locusOfFocus", object()),
|
||||||
|
mock.patch.object(
|
||||||
|
web_script.AXUtilitiesEvent,
|
||||||
|
"get_text_event_reason",
|
||||||
|
return_value=TextEventReason.NAVIGATION_BY_CHARACTER,
|
||||||
|
) as getReason,
|
||||||
|
mock.patch.object(web_script.AXText, "get_selected_ranges", return_value=[]),
|
||||||
|
mock.patch.object(web_script.AXText, "get_caret_offset", return_value=0),
|
||||||
|
mock.patch.object(web_script.AXText, "get_substring", return_value="x"),
|
||||||
|
mock.patch.object(web_script.AXUtilities, "is_text_input", return_value=False),
|
||||||
|
):
|
||||||
|
result = web_script.Script.onTextSelectionChanged(testScript, event)
|
||||||
|
|
||||||
|
self.assertFalse(result)
|
||||||
|
getReason.assert_called_once_with(event)
|
||||||
|
testScript._presentSyntheticCaretSelection.assert_not_called()
|
||||||
|
|
||||||
|
def test_search_reason_preserves_focus_outside_document_suppression(self):
|
||||||
|
testScript = self._make_script()
|
||||||
|
source = object()
|
||||||
|
focus = object()
|
||||||
|
event = mock.Mock(source=source)
|
||||||
|
testScript.utilities.inDocumentContent.side_effect = lambda obj: obj is source
|
||||||
|
|
||||||
|
with (
|
||||||
|
mock.patch.object(web_script.cthulhu_state, "locusOfFocus", focus),
|
||||||
|
mock.patch.object(
|
||||||
|
web_script.AXUtilitiesEvent,
|
||||||
|
"get_text_event_reason",
|
||||||
|
return_value=TextEventReason.SEARCH_PRESENTABLE,
|
||||||
|
) as getReason,
|
||||||
|
):
|
||||||
|
result = web_script.Script.onTextSelectionChanged(testScript, event)
|
||||||
|
|
||||||
|
self.assertTrue(result)
|
||||||
|
getReason.assert_called_once_with(event)
|
||||||
|
|
||||||
|
def test_editing_reason_preserves_default_selection_owner(self):
|
||||||
|
testScript = self._make_script()
|
||||||
|
source = object()
|
||||||
|
event = mock.Mock(source=source)
|
||||||
|
testScript.utilities.textEventIsForNonNavigableTextObject.return_value = False
|
||||||
|
testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = False
|
||||||
|
testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = False
|
||||||
|
|
||||||
|
with (
|
||||||
|
mock.patch.object(web_script.cthulhu_state, "locusOfFocus", source),
|
||||||
|
mock.patch.object(
|
||||||
|
web_script.AXUtilitiesEvent,
|
||||||
|
"get_text_event_reason",
|
||||||
|
return_value=TextEventReason.PASTE,
|
||||||
|
) as getReason,
|
||||||
|
mock.patch.object(web_script.AXText, "get_caret_offset", return_value=0),
|
||||||
|
mock.patch.object(web_script.AXText, "get_substring", return_value="x"),
|
||||||
|
mock.patch.object(web_script.AXUtilities, "is_text_input", return_value=False),
|
||||||
|
):
|
||||||
|
result = web_script.Script.onTextSelectionChanged(testScript, event)
|
||||||
|
|
||||||
|
self.assertFalse(result)
|
||||||
|
getReason.assert_called_once_with(event)
|
||||||
|
|
||||||
|
def test_autocomplete_noise_still_precedes_reason_specific_ownership(self):
|
||||||
|
testScript = self._make_script()
|
||||||
|
event = mock.Mock(source=object())
|
||||||
|
testScript.utilities.eventIsAutocompleteNoise.return_value = True
|
||||||
|
|
||||||
|
with (
|
||||||
|
mock.patch.object(web_script.cthulhu_state, "locusOfFocus", object()),
|
||||||
|
mock.patch.object(
|
||||||
|
web_script.AXUtilitiesEvent,
|
||||||
|
"get_text_event_reason",
|
||||||
|
return_value=TextEventReason.SELECTION_BY_WORD,
|
||||||
|
) as getReason,
|
||||||
|
):
|
||||||
|
result = web_script.Script.onTextSelectionChanged(testScript, event)
|
||||||
|
|
||||||
|
self.assertTrue(result)
|
||||||
|
getReason.assert_called_once_with(event)
|
||||||
|
testScript.utilities.lastInputEventWasCaretNavWithSelection.assert_not_called()
|
||||||
|
|
||||||
|
def test_spinner_noise_still_precedes_reason_specific_ownership(self):
|
||||||
|
testScript = self._make_script()
|
||||||
|
event = mock.Mock(source=object())
|
||||||
|
testScript.utilities.eventIsSpinnerNoise.return_value = True
|
||||||
|
|
||||||
|
with (
|
||||||
|
mock.patch.object(web_script.cthulhu_state, "locusOfFocus", object()),
|
||||||
|
mock.patch.object(
|
||||||
|
web_script.AXUtilitiesEvent,
|
||||||
|
"get_text_event_reason",
|
||||||
|
return_value=TextEventReason.SPIN_BUTTON_VALUE_CHANGE,
|
||||||
|
) as getReason,
|
||||||
|
):
|
||||||
|
result = web_script.Script.onTextSelectionChanged(testScript, event)
|
||||||
|
|
||||||
|
self.assertTrue(result)
|
||||||
|
getReason.assert_called_once_with(event)
|
||||||
|
testScript.utilities.lastInputEventWasCaretNavWithSelection.assert_not_called()
|
||||||
|
|
||||||
|
def test_non_navigable_text_still_suppresses_selection_reason(self):
|
||||||
|
testScript = self._make_script()
|
||||||
|
event = mock.Mock(source=object())
|
||||||
|
testScript.utilities.textEventIsForNonNavigableTextObject.return_value = True
|
||||||
|
|
||||||
|
with (
|
||||||
|
mock.patch.object(web_script.cthulhu_state, "locusOfFocus", object()),
|
||||||
|
mock.patch.object(
|
||||||
|
web_script.AXUtilitiesEvent,
|
||||||
|
"get_text_event_reason",
|
||||||
|
return_value=TextEventReason.SELECTION_BY_LINE,
|
||||||
|
) as getReason,
|
||||||
|
):
|
||||||
|
result = web_script.Script.onTextSelectionChanged(testScript, event)
|
||||||
|
|
||||||
|
self.assertTrue(result)
|
||||||
|
getReason.assert_called_once_with(event)
|
||||||
|
testScript.utilities.lastInputEventWasCaretNavWithSelection.assert_not_called()
|
||||||
|
|
||||||
|
def test_selection_reason_at_embedded_object_offset_defers_to_default(self):
|
||||||
|
testScript = self._make_script()
|
||||||
|
source = object()
|
||||||
|
event = mock.Mock(source=source)
|
||||||
|
testScript.utilities.textEventIsForNonNavigableTextObject.return_value = False
|
||||||
|
testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = False
|
||||||
|
testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = False
|
||||||
|
|
||||||
|
with (
|
||||||
|
mock.patch.object(web_script.cthulhu_state, "locusOfFocus", source),
|
||||||
|
mock.patch.object(
|
||||||
|
web_script.AXUtilitiesEvent,
|
||||||
|
"get_text_event_reason",
|
||||||
|
return_value=TextEventReason.SELECTION_BY_WORD,
|
||||||
|
),
|
||||||
|
mock.patch.object(web_script.AXText, "get_selected_ranges", return_value=[(0, 1)]),
|
||||||
|
mock.patch.object(web_script.AXText, "get_caret_offset", return_value=0),
|
||||||
|
mock.patch.object(
|
||||||
|
web_script.AXText,
|
||||||
|
"get_substring",
|
||||||
|
return_value=web_script.Script.EMBEDDED_OBJECT_CHARACTER,
|
||||||
|
),
|
||||||
|
mock.patch.object(web_script.AXUtilities, "is_text_input", return_value=False),
|
||||||
|
):
|
||||||
|
result = web_script.Script.onTextSelectionChanged(testScript, event)
|
||||||
|
|
||||||
|
self.assertFalse(result)
|
||||||
|
testScript.utilities.lastInputEventWasCaretNavWithSelection.assert_not_called()
|
||||||
|
|
||||||
|
def test_contenteditable_embedded_objects_still_defer_to_default(self):
|
||||||
|
testScript = self._make_script()
|
||||||
|
source = object()
|
||||||
|
event = mock.Mock(source=source)
|
||||||
|
testScript.utilities.textEventIsForNonNavigableTextObject.return_value = False
|
||||||
|
testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = False
|
||||||
|
testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = True
|
||||||
|
|
||||||
|
with (
|
||||||
|
mock.patch.object(web_script.cthulhu_state, "locusOfFocus", source),
|
||||||
|
mock.patch.object(
|
||||||
|
web_script.AXUtilitiesEvent,
|
||||||
|
"get_text_event_reason",
|
||||||
|
return_value=TextEventReason.TYPING,
|
||||||
|
) as getReason,
|
||||||
|
mock.patch.object(web_script.AXUtilities, "is_text_input", return_value=False),
|
||||||
|
):
|
||||||
|
result = web_script.Script.onTextSelectionChanged(testScript, event)
|
||||||
|
|
||||||
|
self.assertFalse(result)
|
||||||
|
getReason.assert_called_once_with(event)
|
||||||
|
|
||||||
def test_web_utilities_all_selected_text_falls_back_to_synthetic_selection(self):
|
def test_web_utilities_all_selected_text_falls_back_to_synthetic_selection(self):
|
||||||
testScript = mock.Mock(pointOfReference={})
|
testScript = mock.Mock(pointOfReference={})
|
||||||
utilities = web_script_utilities.Utilities.__new__(web_script_utilities.Utilities)
|
utilities = web_script_utilities.Utilities.__new__(web_script_utilities.Utilities)
|
||||||
|
|||||||
Reference in New Issue
Block a user