%PDF- %PDF-
Direktori : /usr/lib/python3/dist-packages/orca/scripts/toolkits/WebKitGtk/ |
Current File : //usr/lib/python3/dist-packages/orca/scripts/toolkits/WebKitGtk/script_utilities.py |
# Orca # # Copyright (C) 2010 Joanmarie Diggs # Copyright (C) 2011-2012 Igalia, S.L. # # Author: Joanmarie Diggs <jdiggs@igalia.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., Franklin Street, Fifth Floor, # Boston MA 02110-1301 USA. __id__ = "$Id$" __version__ = "$Revision$" __date__ = "$Date$" __copyright__ = "Copyright (c) 2010 Joanmarie Diggs." \ "Copyright (c) 2011-2012 Igalia, S.L." __license__ = "LGPL" import gi gi.require_version("Atspi", "2.0") from gi.repository import Atspi import re import orca.focus_manager as focus_manager import orca.keybindings as keybindings import orca.script_utilities as script_utilities from orca.ax_component import AXComponent from orca.ax_hypertext import AXHypertext from orca.ax_object import AXObject from orca.ax_text import AXText from orca.ax_utilities import AXUtilities ############################################################################# # # # Utilities # # # ############################################################################# class Utilities(script_utilities.Utilities): def __init__(self, script): """Creates an instance of the Utilities class. Arguments: - script: the script with which this instance is associated. """ super().__init__(script) def isWebKitGtk(self, obj): """Returns True if this object is a WebKitGtk object.""" if not obj: return False attrs = AXObject.get_attributes_dict(obj) return attrs.get('toolkit', '') in ['WebKitGtk', 'WebKitGTK'] def getCaretContext(self): # TODO - JD: This is private, but it's only here temporarily until we # have the shared web content support. obj, offset = self._script._lastCaretContext if not obj and self.isWebKitGtk(focus_manager.getManager().get_locus_of_focus()): obj, offset = super().getCaretContext() return obj, offset def setCaretContext(self, obj, offset): # TODO - JD: This is private, but it's only here temporarily until we # have the shared web content support. self._script._lastCaretContext = obj, offset focus_manager.getManager().set_locus_of_focus(None, obj, notify_script=False) def setCaretPosition(self, obj, offset): self.setCaretContext(obj, offset) self.setCaretOffset(obj, offset) def isReadOnlyTextArea(self, obj): """Returns True if obj is a text entry area that is read only.""" if not AXUtilities.is_entry(obj): return False if AXUtilities.is_read_only(obj): return True return AXUtilities.is_focusable(obj) and not AXUtilities.is_editable(obj) def displayedText(self, obj): """Returns the text being displayed for an object. Arguments: - obj: the object Returns the text being displayed for an object or None if there isn't any text being shown. """ text = script_utilities.Utilities.displayedText(self, obj) if text and text != self.EMBEDDED_OBJECT_CHARACTER: return text if AXUtilities.is_link(obj) or AXUtilities.is_list_item(obj): children = [x for x in AXObject.iter_children(obj)] text = ' '.join(map(self.displayedText, children)) if not text: text = AXHypertext.get_link_basename(obj, remove_extension=True) return text def getLineContentsAtOffset(self, obj, offset, layoutMode=True, useCache=True): return self.getObjectsFromEOCs( obj, offset, Atspi.TextBoundaryType.LINE_START) def getObjectContentsAtOffset(self, obj, offset=0, useCache=True): return self.getObjectsFromEOCs(obj, offset) def getObjectsFromEOCs(self, obj, offset=None, boundary=None): """Breaks the string containing a mixture of text and embedded object characters into a list of (obj, startOffset, endOffset, string) tuples. Arguments - obj: the object whose EOCs we need to expand into tuples - offset: the character offset. If None, use the current offset. - boundary: the text boundary type. If None, get all text. Returns a list of (obj, startOffset, endOffset, string) tuples. """ if not (AXObject.supports_text(obj) and AXObject.supports_hypertext(obj)): return [(obj, 0, 1, '')] string = AXText.get_all_text(obj) if not string: return [(obj, 0, 1, '')] if offset is None: offset = AXText.get_caret_offset(obj) if boundary == Atspi.TextBoundaryType.CHAR: key, mods = self.lastKeyAndModifiers() if (mods & keybindings.SHIFT_MODIFIER_MASK) and key == 'Right': offset -= 1 start, end = AXText.get_character_at_offset(obj, offset)[1:] elif boundary in (None, Atspi.TextBoundaryType.LINE_START): start, end = AXText.get_line_at_offset(obj, offset)[1:] elif boundary == Atspi.TextBoundaryType.SENTENCE_START: start, end = AXText.get_sentence_at_offset(obj, offset)[1:] elif boundary == Atspi.TextBoundaryType.WORD_START: start, end = AXText.get_word_at_offset(obj, offset)[1:] else: start, end = string, 0, AXText.get_character_count(obj) pattern = re.compile(self.EMBEDDED_OBJECT_CHARACTER) offsets = [m.start(0) for m in re.finditer(pattern, string)] offsets = [x for x in offsets if start <= x < end] objects = [] objs = [] for offset in offsets: child = AXHypertext.get_child_at_offset(obj, offset) if child: objs.append(child) def _get_range(obj): return AXHypertext.get_link_start_offset(obj), AXHypertext.get_link_end_offset(obj) ranges = [_get_range(x) for x in objs] for i, (first, last) in enumerate(ranges): objects.append((obj, start, first, string[start:first])) objects.append((objs[i], first, last, '')) start = last objects.append((obj, start, end, string[start:end])) objects = [x for x in objects if x[1] < x[2]] return objects def findPreviousObject(self, obj): """Finds the object before this one.""" if obj is None: return None if AXUtilities.is_link(obj): obj = AXObject.get_parent(obj) prevObj = AXObject.get_previous_object(obj) if AXUtilities.is_list(prevObj) and AXObject.get_child_count(prevObj): child = AXObject.get_child(prevObj, -1) if self.isTextListItem(child): prevObj = child return prevObj def findNextObject(self, obj): """Finds the object after this one.""" if obj is None: return None if AXUtilities.is_link(obj): obj = AXObject.get_parent(obj) nextObj = AXObject.get_next_object(obj) if AXUtilities.is_list(nextObj) and AXObject.get_child_count(nextObj): child = AXObject.get_child(nextObj, 0) if self.isTextListItem(child): nextObj = child return nextObj def isTextListItem(self, obj): """Returns True if obj is an item in a non-selectable list.""" if not AXUtilities.is_list_item(obj): return False parent = AXObject.get_parent(obj) if parent is None: return False return not AXUtilities.is_focusable(parent) def isInlineContainer(self, obj): """Returns True if obj is an inline/non-wrapped container.""" if AXUtilities.is_section(obj): if AXObject.get_child_count(obj) > 1: return AXComponent.on_same_line( AXObject.get_child(obj, 0), AXObject.get_child(obj, 1)) return False if AXUtilities.is_list(obj): if AXUtilities.is_focusable(obj): return False childCount = AXObject.get_child_count(obj) if not childCount: return AXObject.supports_text(obj) if childCount == 1: return False return AXComponent.on_same_line(AXObject.get_child(obj, 0), AXObject.get_child(obj, 1)) return False def isEmbeddedDocument(self, obj): if not self.isWebKitGtk(obj): return False if not AXUtilities.is_document(obj): return False parent = AXObject.get_parent(obj) if not (parent and self.isWebKitGtk(parent)): return False parent = AXObject.get_parent(parent) if not (parent and not self.isWebKitGtk(parent)): return False return True def setCaretAtStart(self, obj): child, index = self.getFirstCaretPosition(obj) if child is not None: AXText.set_caret_offset(child, index) return child, index def treatAsBrowser(self, obj): return self.isEmbeddedDocument(obj) def inDocumentContent(self, obj=None): obj = obj or focus_manager.getManager().get_locus_of_focus() return self.isWebKitGtk(obj)