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 // The offsets are child offsets over the AX tree. Note that we allow |
1834 return createVisiblePosition(Position(node, offset)); | 1826 // for the offset to equal the number of children as |Range| does. |
1827 int childCount = obj->children().size(); | |
1828 // Figure out what it means when |childCount| is 0. | |
dmazzoni
2016/09/16 18:10:56
Is this a TODO/FIXME?
Maybe it should just select
David Tseng
2016/09/16 20:50:31
This isn't a selection but a position.
It's not q
| |
1829 if (childCount == 0 || offset < 0 || offset > childCount) | |
1830 return VisiblePosition(); | |
1831 | |
1832 // Clamp to between 0 and child count - 1. | |
1833 int clampedOffset = | |
1834 static_cast<unsigned>(offset) > (obj->children().size() - 1) ? offse t - 1 : offset; | |
1835 AXObject* childObj = obj->children()[clampedOffset]; | |
1836 Node* childNode = childObj->getNode(); | |
1837 if (!childNode || !childNode->parentNode()) | |
1838 return VisiblePosition(); | |
1839 | |
1840 // The index in parent. | |
1841 int adjustedOffset = -1; | |
1842 NodeList* childNodes = childNode->parentNode()->childNodes(); | |
1843 for (unsigned i = 0; i < childNodes->length(); ++i) { | |
1844 if (childNodes->item(i) == childNode) { | |
1845 adjustedOffset = i; | |
1846 break; | |
1847 } | |
1848 } | |
1849 | |
1850 if (adjustedOffset == -1) | |
1851 return VisiblePosition(); | |
1852 | |
1853 // If we had to clamp the offset above, the client wants to select the | |
1854 // end of the node. | |
1855 if (clampedOffset != offset) | |
1856 adjustedOffset++; | |
1857 | |
1858 return createVisiblePosition(Position::editingPositionOf(childNode->pare ntNode(), adjustedOffset)); | |
1859 } | |
1835 | 1860 |
1836 // If it is a text node, we need to call some utility functions that use a T extIterator | 1861 // 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 | 1862 // to walk the characters of the node and figure out the position correspond ing to the |
1838 // visible character at position |offset|. | 1863 // visible character at position |offset|. |
1839 ContainerNode* parent = node->parentNode(); | 1864 ContainerNode* parent = node->parentNode(); |
1840 if (!parent) | 1865 if (!parent) |
1841 return VisiblePosition(); | 1866 return VisiblePosition(); |
1842 | 1867 |
1843 VisiblePosition nodePosition = blink::visiblePositionBeforeNode(*node); | 1868 VisiblePosition nodePosition = blink::visiblePositionBeforeNode(*node); |
1844 int nodeIndex = blink::indexForVisiblePosition(nodePosition, parent); | 1869 int nodeIndex = blink::indexForVisiblePosition(nodePosition, parent); |
1845 return blink::visiblePositionForIndex(nodeIndex + offset, parent); | 1870 return blink::visiblePositionForIndex(nodeIndex + offset, parent); |
1846 } | 1871 } |
1847 | 1872 |
1848 void AXLayoutObject::setSelection(const AXRange& selection) | 1873 void AXLayoutObject::setSelection(const AXRange& selection) |
1849 { | 1874 { |
1850 if (!getLayoutObject() || !selection.isValid()) | 1875 if (!getLayoutObject() || !selection.isValid()) |
1851 return; | 1876 return; |
1852 | 1877 |
1853 AXObject* anchorObject = selection.anchorObject ? | 1878 AXObject* anchorObject = selection.anchorObject ? |
1854 selection.anchorObject.get() : this; | 1879 selection.anchorObject.get() : this; |
1855 AXObject* focusObject = selection.focusObject ? | 1880 AXObject* focusObject = selection.focusObject ? |
1856 selection.focusObject.get() : this; | 1881 selection.focusObject.get() : this; |
1857 | 1882 |
1858 if (!isValidSelectionBound(anchorObject) | 1883 if (!isValidSelectionBound(anchorObject) |
1859 || !isValidSelectionBound(focusObject)) { | 1884 || !isValidSelectionBound(focusObject)) { |
1860 return; | 1885 return; |
1861 } | 1886 } |
1862 | 1887 |
1888 // The selection offsets are offsets into the accessible value. | |
1863 if (anchorObject == focusObject | 1889 if (anchorObject == focusObject |
1864 && anchorObject->getLayoutObject()->isTextControl()) { | 1890 && anchorObject->getLayoutObject()->isTextControl()) { |
1865 HTMLTextFormControlElement* textControl = toLayoutTextControl( | 1891 HTMLTextFormControlElement* textControl = toLayoutTextControl( |
1866 anchorObject->getLayoutObject())->textFormControlElement(); | 1892 anchorObject->getLayoutObject())->textFormControlElement(); |
1867 if (selection.anchorOffset <= selection.focusOffset) { | 1893 if (selection.anchorOffset <= selection.focusOffset) { |
1868 textControl->setSelectionRange( | 1894 textControl->setSelectionRange( |
1869 selection.anchorOffset, selection.focusOffset, | 1895 selection.anchorOffset, selection.focusOffset, |
1870 SelectionHasForwardDirection); | 1896 SelectionHasForwardDirection); |
1871 } else { | 1897 } else { |
1872 textControl->setSelectionRange( | 1898 textControl->setSelectionRange( |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2371 | 2397 |
2372 bool AXLayoutObject::elementAttributeValue(const QualifiedName& attributeName) c onst | 2398 bool AXLayoutObject::elementAttributeValue(const QualifiedName& attributeName) c onst |
2373 { | 2399 { |
2374 if (!m_layoutObject) | 2400 if (!m_layoutObject) |
2375 return false; | 2401 return false; |
2376 | 2402 |
2377 return equalIgnoringCase(getAttribute(attributeName), "true"); | 2403 return equalIgnoringCase(getAttribute(attributeName), "true"); |
2378 } | 2404 } |
2379 | 2405 |
2380 } // namespace blink | 2406 } // namespace blink |
OLD | NEW |