OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 1799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1810 } | 1810 } |
1811 | 1811 |
1812 | 1812 |
1813 // | 1813 // |
1814 // Modify or take an action on an object. | 1814 // Modify or take an action on an object. |
1815 // | 1815 // |
1816 | 1816 |
1817 // Convert from an accessible object and offset to a VisiblePosition. | 1817 // Convert from an accessible object and offset to a VisiblePosition. |
1818 static VisiblePosition toVisiblePosition(AXObject* obj, int offset) | 1818 static VisiblePosition toVisiblePosition(AXObject* obj, int offset) |
1819 { | 1819 { |
1820 // First walk up until we find an accessible object with an associated node. | 1820 if (!obj->getNode()) |
1821 AXObject* runner = obj; | |
1822 Node* node = nullptr; | |
1823 while (runner && !node) { | |
1824 node = runner->getNode(); | |
1825 runner = runner->parentObject(); | |
1826 } | |
1827 | |
1828 if (!node) | |
1829 return VisiblePosition(); | 1821 return VisiblePosition(); |
1830 | 1822 |
1831 // If it's not a text node, no conversion is necessary, just create a Visibl
ePosition | 1823 Node* node = obj->getNode(); |
1832 // with this node and offset. | 1824 if (!node->isTextNode()) { |
1833 if (!node->isTextNode()) | 1825 int childCount = obj->children().size(); |
1834 return createVisiblePosition(Position(node, offset)); | 1826 |
| 1827 // Place position immediately before the container node, if there was no
children. |
| 1828 if (childCount == 0) { |
| 1829 if (!obj->parentObject()) |
| 1830 return VisiblePosition(); |
| 1831 return toVisiblePosition(obj->parentObject(), obj->indexInParent()); |
| 1832 } |
| 1833 |
| 1834 // The offsets are child offsets over the AX tree. Note that we allow |
| 1835 // for the offset to equal the number of children as |Range| does. |
| 1836 if (offset < 0 || offset > childCount) |
| 1837 return VisiblePosition(); |
| 1838 |
| 1839 // Clamp to between 0 and child count - 1. |
| 1840 int clampedOffset = |
| 1841 static_cast<unsigned>(offset) > (obj->children().size() - 1) ? offse
t - 1 : offset; |
| 1842 AXObject* childObj = obj->children()[clampedOffset]; |
| 1843 Node* childNode = childObj->getNode(); |
| 1844 if (!childNode || !childNode->parentNode()) |
| 1845 return VisiblePosition(); |
| 1846 |
| 1847 // The index in parent. |
| 1848 int adjustedOffset = childNode->nodeIndex(); |
| 1849 |
| 1850 // If we had to clamp the offset above, the client wants to select the |
| 1851 // end of the node. |
| 1852 if (clampedOffset != offset) |
| 1853 adjustedOffset++; |
| 1854 |
| 1855 return createVisiblePosition(Position::editingPositionOf(childNode->pare
ntNode(), adjustedOffset)); |
| 1856 } |
1835 | 1857 |
1836 // If it is a text node, we need to call some utility functions that use a T
extIterator | 1858 // If it is a text node, we need to call some utility functions that use a T
extIterator |
1837 // to walk the characters of the node and figure out the position correspond
ing to the | 1859 // to walk the characters of the node and figure out the position correspond
ing to the |
1838 // visible character at position |offset|. | 1860 // visible character at position |offset|. |
1839 ContainerNode* parent = node->parentNode(); | 1861 ContainerNode* parent = node->parentNode(); |
1840 if (!parent) | 1862 if (!parent) |
1841 return VisiblePosition(); | 1863 return VisiblePosition(); |
1842 | 1864 |
1843 VisiblePosition nodePosition = blink::visiblePositionBeforeNode(*node); | 1865 VisiblePosition nodePosition = blink::visiblePositionBeforeNode(*node); |
1844 int nodeIndex = blink::indexForVisiblePosition(nodePosition, parent); | 1866 int nodeIndex = blink::indexForVisiblePosition(nodePosition, parent); |
1845 return blink::visiblePositionForIndex(nodeIndex + offset, parent); | 1867 return blink::visiblePositionForIndex(nodeIndex + offset, parent); |
1846 } | 1868 } |
1847 | 1869 |
1848 void AXLayoutObject::setSelection(const AXRange& selection) | 1870 void AXLayoutObject::setSelection(const AXRange& selection) |
1849 { | 1871 { |
1850 if (!getLayoutObject() || !selection.isValid()) | 1872 if (!getLayoutObject() || !selection.isValid()) |
1851 return; | 1873 return; |
1852 | 1874 |
1853 AXObject* anchorObject = selection.anchorObject ? | 1875 AXObject* anchorObject = selection.anchorObject ? |
1854 selection.anchorObject.get() : this; | 1876 selection.anchorObject.get() : this; |
1855 AXObject* focusObject = selection.focusObject ? | 1877 AXObject* focusObject = selection.focusObject ? |
1856 selection.focusObject.get() : this; | 1878 selection.focusObject.get() : this; |
1857 | 1879 |
1858 if (!isValidSelectionBound(anchorObject) | 1880 if (!isValidSelectionBound(anchorObject) |
1859 || !isValidSelectionBound(focusObject)) { | 1881 || !isValidSelectionBound(focusObject)) { |
1860 return; | 1882 return; |
1861 } | 1883 } |
1862 | 1884 |
| 1885 // The selection offsets are offsets into the accessible value. |
1863 if (anchorObject == focusObject | 1886 if (anchorObject == focusObject |
1864 && anchorObject->getLayoutObject()->isTextControl()) { | 1887 && anchorObject->getLayoutObject()->isTextControl()) { |
1865 HTMLTextFormControlElement* textControl = toLayoutTextControl( | 1888 HTMLTextFormControlElement* textControl = toLayoutTextControl( |
1866 anchorObject->getLayoutObject())->textFormControlElement(); | 1889 anchorObject->getLayoutObject())->textFormControlElement(); |
1867 if (selection.anchorOffset <= selection.focusOffset) { | 1890 if (selection.anchorOffset <= selection.focusOffset) { |
1868 textControl->setSelectionRange( | 1891 textControl->setSelectionRange( |
1869 selection.anchorOffset, selection.focusOffset, | 1892 selection.anchorOffset, selection.focusOffset, |
1870 SelectionHasForwardDirection); | 1893 SelectionHasForwardDirection); |
1871 } else { | 1894 } else { |
1872 textControl->setSelectionRange( | 1895 textControl->setSelectionRange( |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2371 | 2394 |
2372 bool AXLayoutObject::elementAttributeValue(const QualifiedName& attributeName) c
onst | 2395 bool AXLayoutObject::elementAttributeValue(const QualifiedName& attributeName) c
onst |
2373 { | 2396 { |
2374 if (!m_layoutObject) | 2397 if (!m_layoutObject) |
2375 return false; | 2398 return false; |
2376 | 2399 |
2377 return equalIgnoringCase(getAttribute(attributeName), "true"); | 2400 return equalIgnoringCase(getAttribute(attributeName), "true"); |
2378 } | 2401 } |
2379 | 2402 |
2380 } // namespace blink | 2403 } // namespace blink |
OLD | NEW |