diff --git a/src/cthulhu/scripts/web/script.py b/src/cthulhu/scripts/web/script.py index e876679..cba6853 100644 --- a/src/cthulhu/scripts/web/script.py +++ b/src/cthulhu/scripts/web/script.py @@ -2265,8 +2265,14 @@ class Script(default.Script): # We should get proper state-changed events for these. if self.utilities.inDocumentContent(event.source): - msg = "WEB: Ignoring because object:state-changed-focused expected." + if self._getQueuedEvent("object:state-changed:focused", True): + msg = "WEB: Ignoring because object:state-changed-focused expected." + debug.printMessage(debug.LEVEL_INFO, msg, True) + return True + + msg = "WEB: Handling focus event in document content; focused event missing." debug.printMessage(debug.LEVEL_INFO, msg, True) + cthulhu.setLocusOfFocus(event, event.source) return True return False diff --git a/src/cthulhu/scripts/web/script_utilities.py b/src/cthulhu/scripts/web/script_utilities.py index 7655198..df97ec8 100644 --- a/src/cthulhu/scripts/web/script_utilities.py +++ b/src/cthulhu/scripts/web/script_utilities.py @@ -307,20 +307,69 @@ class Utilities(script_utilities.Utilities): return True def activeDocument(self, window=None): - documents = self._getDocumentsEmbeddedBy(window or cthulhu_state.activeWindow) + window = window or cthulhu_state.activeWindow + documents = self._getDocumentsEmbeddedBy(window) documents = list(filter(AXUtilities.is_showing, documents)) + + def documentHasUri(document): + return bool(AXDocument.get_uri(document)) + + def findDocumentWithUri(searchRoot): + if not searchRoot: + return None + return AXObject.find_descendant( + searchRoot, + lambda obj: AXUtilities.is_document_web(obj) + and AXUtilities.is_showing(obj) + and AXDocument.get_uri(obj) + ) + if len(documents) == 1: - return documents[0] + document = documents[0] + if documentHasUri(document): + return document + + fallback = findDocumentWithUri(window) + if fallback and fallback != document: + tokens = ["WEB: Using fallback active document with URI:", fallback] + debug.printTokens(debug.LEVEL_INFO, tokens, True) + return fallback + + return document # If multiple documents are showing (e.g., multi-tab browser), use the # locus of focus to determine which document is currently active. if documents: focusDoc = self.getTopLevelDocumentForObject(cthulhu_state.locusOfFocus) + if focusDoc in documents and documentHasUri(focusDoc): + tokens = ["WEB: Multiple showing documents, using focus-based document:", focusDoc] + debug.printTokens(debug.LEVEL_INFO, tokens, True) + return focusDoc + + uriDoc = next((doc for doc in documents if documentHasUri(doc)), None) + if uriDoc and uriDoc != focusDoc: + tokens = ["WEB: Multiple showing documents, using URI-based document:", uriDoc] + debug.printTokens(debug.LEVEL_INFO, tokens, True) + return uriDoc + if focusDoc in documents: tokens = ["WEB: Multiple showing documents, using focus-based document:", focusDoc] debug.printTokens(debug.LEVEL_INFO, tokens, True) return focusDoc + fallback = findDocumentWithUri(window) + if fallback: + tokens = ["WEB: Multiple showing documents, using fallback document:", fallback] + debug.printTokens(debug.LEVEL_INFO, tokens, True) + return fallback + + if window: + fallback = findDocumentWithUri(window) + if fallback: + tokens = ["WEB: Using fallback document:", fallback] + debug.printTokens(debug.LEVEL_INFO, tokens, True) + return fallback + return None def documentFrame(self, obj=None):