[orca] Clean-up web script's onCaretMoved()



commit cf8edb98c551671367af130b8cfaf7d3d8baae19
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Mon Apr 20 21:03:29 2020 -0400

    Clean-up web script's onCaretMoved()
    
    * Eliminate some redundant checks:
      - inContextMenu() covered by not eventIsFromLocusOfFocusDocument()
      - queryNonEmptyText() returns None for things where caret-moved
        events should not be presented anyway
      - Because we're getting the first caret context, we shouldn't have
        to handle that context being an embedded object character
    
    * Having (hopefully) handled all the special cases, just update the
      locusOfFocus and let the default script do its thing. It shouldn't
      matter if the object is editable or contenteditable or non-editable
      text being navigated in focus mode. If it does matter, then we're
      probably doing something else wrong.
    
    * Prevent arrowing left/right amongst text blocks in focus mode to
      cause the entire line of the new location to be presented as a
      consequence of the caret moved event.
    
    * Fix bug causing caret-moved event not being presented due to it
      being seen as handled as a text selection change.
    
    * Improve identification of caret moving to same page link so that
      we're not silent.

 src/orca/script_utilities.py             |   6 ++
 src/orca/scripts/default.py              |   2 +
 src/orca/scripts/web/script.py           | 110 ++++++++-----------------------
 src/orca/scripts/web/script_utilities.py |  23 ++++---
 4 files changed, 51 insertions(+), 90 deletions(-)
---
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index 6616e88a3..e15a772bc 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -4969,6 +4969,12 @@ class Utilities:
 
         return True
 
+    def lastInputEventWasCaretNav(self):
+        return self.lastInputEventWasCharNav() \
+            or self.lastInputEventWasWordNav() \
+            or self.lastInputEventWasLineNav() \
+            or self.lastInputEventWasLineBoundaryNav()
+
     def lastInputEventWasCharNav(self):
         keyString, mods = self.lastKeyAndModifiers()
         if not keyString in ["Left", "Right"]:
diff --git a/src/orca/scripts/default.py b/src/orca/scripts/default.py
index 3277faa37..eb40e4cd0 100644
--- a/src/orca/scripts/default.py
+++ b/src/orca/scripts/default.py
@@ -2309,6 +2309,8 @@ class Script(script.Script):
         else:
             start, end, string = self.utilities.getCachedTextSelection(obj)
             if string and self.utilities.handleTextSelectionChange(obj):
+                msg = "DEFAULT: Event handled as text selection change"
+                debug.println(debug.LEVEL_INFO, msg, True)
                 return
 
         msg = "DEFAULT: Presenting text at new caret position"
diff --git a/src/orca/scripts/web/script.py b/src/orca/scripts/web/script.py
index 7ee4d28ae..2dea942d8 100644
--- a/src/orca/scripts/web/script.py
+++ b/src/orca/scripts/web/script.py
@@ -1509,13 +1509,8 @@ class Script(default.Script):
             self._saveFocusedObjectInfo(orca_state.locusOfFocus)
             return True
 
-        if self.utilities.inContextMenu():
-            msg = "WEB: Event ignored: In context menu"
-            debug.println(debug.LEVEL_INFO, msg, True)
-            return True
-
-        if self.utilities.eventIsAutocompleteNoise(event):
-            msg = "WEB: Event ignored: Autocomplete noise"
+        if not self.utilities.eventIsFromLocusOfFocusDocument(event):
+            msg = "WEB: Event ignored: Not from locus of focus document"
             debug.println(debug.LEVEL_INFO, msg, True)
             return True
 
@@ -1525,104 +1520,55 @@ class Script(default.Script):
             self._saveLastCursorPosition(event.source, event.detail1)
             return True
 
-        if self._inFocusMode and self.utilities.caretMovedOutsideActiveGrid(event):
-            msg = "WEB: Event ignored: Caret moved outside active grid during focus mode"
-            debug.println(debug.LEVEL_INFO, msg, True)
-            return True
-
-        obj, offset = self.utilities.findFirstCaretContext(event.source, event.detail1)
-
-        if self.utilities.caretMovedToSamePageFragment(event):
-            msg = "WEB: Event handled: Caret moved to fragment"
+        if self.utilities.textEventIsDueToDeletion(event):
+            msg = "WEB: Event handled: Updating position due to deletion"
             debug.println(debug.LEVEL_INFO, msg, True)
-            self.utilities.setCaretContext(obj, offset)
-            orca.setLocusOfFocus(event, obj)
+            self._saveLastCursorPosition(event.source, event.detail1)
             return True
 
-        # We want to do this check after the same-page-fragment check because some
-        # fragments start with non-navigable text objects.
-        if self.utilities.textEventIsForNonNavigableTextObject(event):
-            msg = "WEB: Event ignored: Event source is non-navigable text object"
+        if self.utilities.eventIsAutocompleteNoise(event):
+            msg = "WEB: Event ignored: Autocomplete noise"
             debug.println(debug.LEVEL_INFO, msg, True)
             return True
 
-        if self.utilities.lastInputEventWasPageNav() \
-           and not self.utilities.isLink(event.source) \
-           and not event.source.getRole() == pyatspi.ROLE_COMBO_BOX:
-            msg = "WEB: Event handled: Caret moved due to scrolling"
+        if self._inFocusMode and self.utilities.caretMovedOutsideActiveGrid(event):
+            msg = "WEB: Event ignored: Caret moved outside active grid during focus mode"
             debug.println(debug.LEVEL_INFO, msg, True)
-            self.utilities.setCaretContext(obj, offset)
-            orca.setLocusOfFocus(event, obj, force=True)
             return True
 
-        if self.utilities.isContentEditableWithEmbeddedObjects(event.source):
-            msg = "WEB: In content editable with embedded objects"
+        if self.utilities.treatEventAsSpinnerValueChange(event):
+            msg = "WEB: Event handled as the value-change event we wish we'd get"
             debug.println(debug.LEVEL_INFO, msg, True)
-            if not self.utilities.eventIsFromLocusOfFocusDocument(event):
-                msg = "WEB: Event ignored: Not from locus of focus document"
-                debug.println(debug.LEVEL_INFO, msg, True)
-                return True
-
-            self.utilities.setCaretContext(obj, offset)
-            notify = not self.utilities.lastInputEventWasCharNav() \
-                     and not self.utilities.isEntryDescendant(obj)
-            orca.setLocusOfFocus(event, event.source, notify)
-            return False
-
-        text = self.utilities.queryNonEmptyText(event.source)
-        if not text:
-            if event.source.getRole() == pyatspi.ROLE_LINK:
-                msg = "WEB: Event handled: Was for non-text link"
-                debug.println(debug.LEVEL_INFO, msg, True)
-                self.utilities.setCaretContext(event.source, event.detail1)
-                orca.setLocusOfFocus(event, event.source)
-            else:
-                msg = "WEB: Event ignored: Was for non-text non-link"
-                debug.println(debug.LEVEL_INFO, msg, True)
+            self.updateBraille(event.source)
+            self._presentTextAtNewCaretPosition(event)
             return True
 
-        char = text.getText(event.detail1, event.detail1+1)
-        try:
-            isEditable = obj.getState().contains(pyatspi.STATE_EDITABLE)
-        except:
-            isEditable = False
-
-        if not char and not isEditable:
-            msg = "WEB: Event ignored: Was for empty char in non-editable text"
+        if not self.utilities.queryNonEmptyText(event.source):
+            msg = "WEB: Event ignored: Was for object we're treating as textless"
             debug.println(debug.LEVEL_INFO, msg, True)
             return True
 
-        if char == self.EMBEDDED_OBJECT_CHARACTER:
-            if not self.utilities.isTextBlockElement(obj):
-                msg = "WEB: Event ignored: Was for embedded non-textblock"
-                debug.println(debug.LEVEL_INFO, msg, True)
-                return True
+        obj, offset = self.utilities.findFirstCaretContext(event.source, event.detail1)
+        notify = force = handled = False
 
-            msg = "WEB: Setting locusOfFocus, context to: %s, %i" % (obj, offset)
+        if self.utilities.lastInputEventWasPageNav():
+            msg = "WEB: Caret moved due to scrolling."
             debug.println(debug.LEVEL_INFO, msg, True)
-            self.utilities.setCaretContext(obj, offset)
-            orca.setLocusOfFocus(event, obj)
-            return True
+            notify = force = handled = True
 
-        if self.utilities.treatEventAsSpinnerValueChange(event):
-            msg = "WEB: Event handled as the value-change event we wish we'd get"
+        elif self.utilities.caretMovedToSamePageFragment(event):
+            msg = "WEB: Caret moved to fragment."
             debug.println(debug.LEVEL_INFO, msg, True)
-            self.updateBraille(event.source)
-            self._presentTextAtNewCaretPosition(event)
-            return True
+            notify = force = handled = True
 
-        if not _settingsManager.getSetting('caretNavigationEnabled') \
-           or self._inFocusMode or isEditable:
-            msg = "WEB: Setting locusOfFocus, context to: %s, %i" % (event.source, event.detail1)
+        elif self.utilities.lastInputEventWasCaretNav():
+            msg = "WEB: Caret moved to due native caret navigation."
             debug.println(debug.LEVEL_INFO, msg, True)
-            self.utilities.setCaretContext(event.source, event.detail1)
-            notify = event.source.getState().contains(pyatspi.STATE_FOCUSED)
-            orca.setLocusOfFocus(event, event.source, notify)
-            return False
 
-        self.utilities.setCaretContext(obj, offset)
-        msg = "WEB: Setting context to: %s, %i" % (obj, offset)
+        msg = "WEB: Setting context and focus to: %s, %i" % (obj, offset)
         debug.println(debug.LEVEL_INFO, msg, True)
+        self.utilities.setCaretContext(obj, offset)
+        orca.setLocusOfFocus(event, obj, notify, force)
         return False
 
     def onCheckedChanged(self, event):
diff --git a/src/orca/scripts/web/script_utilities.py b/src/orca/scripts/web/script_utilities.py
index e48f51960..d33ac72e4 100644
--- a/src/orca/scripts/web/script_utilities.py
+++ b/src/orca/scripts/web/script_utilities.py
@@ -1827,6 +1827,9 @@ class Utilities(script_utilities.Utilities):
             newSubtree = self._getSubtree(start, end)
             descendants = sorted(set(oldSubtree).union(newSubtree), key=functools.cmp_to_key(_cmp))
 
+        if not descendants:
+            return False
+
         for descendant in descendants:
             if descendant not in (oldStart, oldEnd, start, end) \
                and pyatspi.findAncestor(descendant, lambda x: x in descendants):
@@ -4200,18 +4203,22 @@ class Utilities(script_utilities.Utilities):
         if event.source.getState().contains(pyatspi.STATE_EDITABLE):
             return False
 
-        oldFocus = oldFocus or orca_state.locusOfFocus
-        linkURI = self.uri(oldFocus)
         docURI = self.documentFrameURI()
-        if linkURI == docURI:
-            return True
+        fragment = urllib.parse.urlparse(docURI).fragment
+        if not fragment:
+            return False
 
         sourceID = self._getID(event.source)
-        if sourceID:
-            parseResult = urllib.parse.urlparse(docURI)
-            return parseResult.fragment == sourceID
+        if sourceID and fragment == sourceID:
+            return True
 
-        return False
+        oldFocus = oldFocus or orca_state.locusOfFocus
+        if self.isLink(oldFocus):
+            link = oldFocus
+        else:
+            link = pyatspi.findAncestor(oldFocus, self.isLink)
+
+        return link and self.uri(link) == docURI
 
     def isChildOfCurrentFragment(self, obj):
         parseResult = urllib.parse.urlparse(self.documentFrameURI())


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]