int Position::computeOffsetInContainerNode() const { if (!m_anchorNode) return 0; switch (anchorType()) { case PositionIsOffsetInAnchor: return std::min(lastOffsetInNode(m_anchorNode.get()), m_offset); case PositionIsBeforeAnchor: return m_anchorNode->nodeIndex(); case PositionIsAfterAnchor: return m_anchorNode->nodeIndex() + 1; } ASSERT_NOT_REACHED(); return 0; }
PassRefPtr<Range> HTMLTextFormControlElement::selection() const { #if defined(S_CLEAR_SELECTION_ONAUTOFOCUS) if (!renderer() || !isTextFormControl()) #else if (!renderer() || !isTextFormControl() || !hasCachedSelection()) #endif return 0; int start = m_cachedSelectionStart; int end = m_cachedSelectionEnd; ASSERT(start <= end); HTMLElement* innerText = innerTextElement(); if (!innerText) return 0; if (!innerText->firstChild()) return Range::create(document(), innerText, 0, innerText, 0); int offset = 0; Node* startNode = 0; Node* endNode = 0; for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(*node, innerText)) { ASSERT(!node->firstChild()); ASSERT(node->isTextNode() || node->hasTagName(brTag)); int length = node->isTextNode() ? lastOffsetInNode(node) : 1; if (offset <= start && start <= offset + length) setContainerAndOffsetForRange(node, start - offset, startNode, start); if (offset <= end && end <= offset + length) { setContainerAndOffsetForRange(node, end - offset, endNode, end); break; } offset += length; } if (!startNode || !endNode) return 0; return Range::create(document(), startNode, start, endNode, end); }
int PositionTemplate<Strategy>::computeOffsetInContainerNode() const { if (!m_anchorNode) return 0; switch (anchorType()) { case PositionAnchorType::BeforeChildren: return 0; case PositionAnchorType::AfterChildren: return lastOffsetInNode(m_anchorNode.get()); case PositionAnchorType::OffsetInAnchor: return minOffsetForNode(m_anchorNode.get(), m_offset); case PositionAnchorType::BeforeAnchor: return Strategy::index(*m_anchorNode); case PositionAnchorType::AfterAnchor: return Strategy::index(*m_anchorNode) + 1; } ASSERT_NOT_REACHED(); return 0; }
PassRefPtrWillBeRawPtr<Range> HTMLTextFormControlElement::selection() const { if (!renderer() || !isTextFormControl()) return nullptr; int start = m_cachedSelectionStart; int end = m_cachedSelectionEnd; ASSERT(start <= end); HTMLElement* innerText = innerEditorElement(); if (!innerText) return nullptr; if (!innerText->firstChild()) return Range::create(document(), innerText, 0, innerText, 0); int offset = 0; Node* startNode = 0; Node* endNode = 0; for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(*node, innerText)) { ASSERT(!node->firstChild()); ASSERT(node->isTextNode() || isHTMLBRElement(*node)); int length = node->isTextNode() ? lastOffsetInNode(node) : 1; if (offset <= start && start <= offset + length) setContainerAndOffsetForRange(node, start - offset, startNode, start); if (offset <= end && end <= offset + length) { setContainerAndOffsetForRange(node, end - offset, endNode, end); break; } offset += length; } if (!startNode || !endNode) return nullptr; return Range::create(document(), startNode, start, endNode, end); }
Range* HTMLTextFormControlElement::selection() const { if (!layoutObject() || !isTextFormControl()) return nullptr; int start = m_cachedSelectionStart; int end = m_cachedSelectionEnd; ASSERT(start <= end); HTMLElement* innerText = innerEditorElement(); if (!innerText) return nullptr; if (!innerText->hasChildren()) return Range::create(document(), innerText, 0, innerText, 0); int offset = 0; Node* startNode = 0; Node* endNode = 0; for (Node& node : NodeTraversal::descendantsOf(*innerText)) { ASSERT(!node.hasChildren()); ASSERT(node.isTextNode() || isHTMLBRElement(node)); int length = node.isTextNode() ? lastOffsetInNode(&node) : 1; if (offset <= start && start <= offset + length) setContainerAndOffsetForRange(&node, start - offset, startNode, start); if (offset <= end && end <= offset + length) { setContainerAndOffsetForRange(&node, end - offset, endNode, end); break; } offset += length; } if (!startNode || !endNode) return nullptr; return Range::create(document(), startNode, start, endNode, end); }
void SimplifiedBackwardsTextIteratorAlgorithm<Strategy>::init(Node* startNode, Node* endNode, int startOffset, int endOffset) { if (!startNode->offsetInCharacters() && startOffset >= 0) { // NodeTraversal::childAt() will return 0 if the offset is out of range. We rely on this behavior // instead of calling countChildren() to avoid traversing the children twice. if (Node* childAtOffset = NodeTraversal::childAt(*startNode, startOffset)) { startNode = childAtOffset; startOffset = 0; } } if (!endNode->offsetInCharacters() && endOffset > 0) { // NodeTraversal::childAt() will return 0 if the offset is out of range. We rely on this behavior // instead of calling countChildren() to avoid traversing the children twice. if (Node* childAtOffset = NodeTraversal::childAt(*endNode, endOffset - 1)) { endNode = childAtOffset; endOffset = lastOffsetInNode(endNode); } } m_node = endNode; m_fullyClippedStack.setUpFullyClippedStack(m_node); m_offset = endOffset; m_handledNode = false; m_handledChildren = !endOffset; m_startNode = startNode; m_startOffset = startOffset; m_endNode = endNode; m_endOffset = endOffset; #if ENABLE(ASSERT) // Need this just because of the assert. m_positionNode = endNode; #endif m_havePassedStartNode = false; advance(); }