void DOMSelection::setBaseAndExtent(Node* baseNode, int baseOffset, Node* extentNode, int extentOffset, ExceptionCode& ec) { if (!m_frame) return; if (baseOffset < 0 || extentOffset < 0) { ec = INDEX_SIZE_ERR; return; } if (!isValidForPosition(baseNode) || !isValidForPosition(extentNode)) return; // FIXME: Eliminate legacy editing positions VisiblePosition visibleBase = VisiblePosition(createLegacyEditingPosition(baseNode, baseOffset), DOWNSTREAM); VisiblePosition visibleExtent = VisiblePosition(createLegacyEditingPosition(extentNode, extentOffset), DOWNSTREAM); m_frame->selection().moveTo(visibleBase, visibleExtent); }
void DOMSelection::setPosition(Node* node, unsigned offset) { if (!m_frame) return; if (!isValidForPosition(node)) return; // FIXME: Eliminate legacy editing positions m_frame->selection().moveTo(createLegacyEditingPosition(node, offset), DOWNSTREAM); }
void DOMSelection::setPosition(Node* node, int offset, ExceptionCode& ec) { if (!m_frame) return; if (offset < 0) { ec = INDEX_SIZE_ERR; return; } if (!isValidForPosition(node)) return; // FIXME: Eliminate legacy editing positions m_frame->selection()->moveTo(VisiblePosition(createLegacyEditingPosition(node, offset), DOWNSTREAM)); }
void DOMSelection::setBaseAndExtent(Node* baseNode, int baseOffset, Node* extentNode, int extentOffset, ExceptionState& exceptionState) { if (!m_frame) return; if (baseOffset < 0) { exceptionState.throwDOMException(IndexSizeError, String::number(baseOffset) + " is not a valid base offset."); return; } if (extentOffset < 0) { exceptionState.throwDOMException(IndexSizeError, String::number(extentOffset) + " is not a valid extent offset."); return; } if (!isValidForPosition(baseNode) || !isValidForPosition(extentNode)) return; // FIXME: Eliminate legacy editing positions VisiblePosition visibleBase = VisiblePosition(createLegacyEditingPosition(baseNode, baseOffset), DOWNSTREAM); VisiblePosition visibleExtent = VisiblePosition(createLegacyEditingPosition(extentNode, extentOffset), DOWNSTREAM); m_frame->selection().moveTo(visibleBase, visibleExtent); }
void DOMSelection::setPosition(Node* node, int offset, ExceptionState& exceptionState) { if (!m_frame) return; if (offset < 0) { exceptionState.throwDOMException(IndexSizeError, String::number(offset) + " is not a valid offset."); return; } if (!isValidForPosition(node)) return; // FIXME: Eliminate legacy editing positions m_frame->selection().moveTo(VisiblePosition(createLegacyEditingPosition(node, offset), DOWNSTREAM)); }
void DOMSelection::extend(Node& node, unsigned offset, ExceptionCode& ec) { if (!m_frame) return; if (offset > (node.offsetInCharacters() ? caretMaxOffset(node) : node.countChildNodes())) { ec = INDEX_SIZE_ERR; return; } if (!isValidForPosition(&node)) return; // FIXME: Eliminate legacy editing positions m_frame->selection().setExtent(createLegacyEditingPosition(&node, offset), DOWNSTREAM); }
static void sendAXTextChangedIgnoringLineBreaks(Node* node, AXTextEditType type) { if (!node) return; if (!AXObjectCache::accessibilityEnabled()) return; String text = node->nodeValue(); // Don't consider linebreaks in this command if (text == "\n") return; if (AXObjectCache* cache = node->document().existingAXObjectCache()) { Position position = is<Text>(node) ? Position(downcast<Text>(node), 0) : createLegacyEditingPosition(node, 0); cache->postTextStateChangeNotification(node, type, text, VisiblePosition(position)); } }
void DOMSelection::extend(Node* node, int offset, ExceptionCode& ec) { if (!m_frame) return; if (!node) { ec = TYPE_MISMATCH_ERR; return; } if (offset < 0 || offset > (node->offsetInCharacters() ? caretMaxOffset(node) : (int)node->childNodeCount())) { ec = INDEX_SIZE_ERR; return; } if (!isValidForPosition(node)) return; // FIXME: Eliminate legacy editing positions m_frame->selection()->setExtent(VisiblePosition(createLegacyEditingPosition(node, offset), DOWNSTREAM)); }
void DOMSelection::extend(Node* node, int offset, ExceptionState& exceptionState) { ASSERT(node); if (!m_frame) return; if (offset < 0) { exceptionState.throwDOMException(IndexSizeError, String::number(offset) + " is not a valid offset."); return; } if (offset > (node->offsetInCharacters() ? caretMaxOffset(node) : (int)node->countChildren())) { exceptionState.throwDOMException(IndexSizeError, String::number(offset) + " is larger than the given node's length."); return; } if (!isValidForPosition(node)) return; // FIXME: Eliminate legacy editing positions m_frame->selection().setExtent(VisiblePosition(createLegacyEditingPosition(node, offset), DOWNSTREAM)); }
void DOMSelection::extend(Node* node, int offset, ExceptionState& exceptionState) { ASSERT(node); if (!m_frame) return; if (offset < 0) { exceptionState.throwDOMException(IndexSizeError, String::number(offset) + " is not a valid offset."); return; } if (static_cast<unsigned>(offset) > node->lengthOfContents()) { exceptionState.throwDOMException(IndexSizeError, String::number(offset) + " is larger than the given node's length."); return; } if (!isValidForPosition(node)) return; // FIXME: Eliminate legacy editing positions m_frame->selection().setExtent(VisiblePosition(createLegacyEditingPosition(node, offset), DOWNSTREAM)); }
void InsertNodeBeforeCommand::doUnapply() { if (!isEditableNode(*m_insertChild)) return; // Need to notify this before actually deleting the text if (shouldPostAccessibilityNotification()) { Position position = is<Text>(m_insertChild.get()) ? Position(downcast<Text>(m_insertChild.get()), 0) : createLegacyEditingPosition(m_insertChild.get(), 0); notifyAccessibilityForTextChange(m_insertChild.get(), unapplyEditType(), m_insertChild->nodeValue(), VisiblePosition(position)); } m_insertChild->remove(IGNORE_EXCEPTION); }
void InsertNodeBeforeCommand::doApply() { ContainerNode* parent = m_refChild->parentNode(); if (!parent || (m_shouldAssumeContentIsAlwaysEditable == DoNotAssumeContentIsAlwaysEditable && !isEditableNode(*parent))) return; ASSERT(isEditableNode(*parent)); parent->insertBefore(*m_insertChild, m_refChild.get(), IGNORE_EXCEPTION); if (shouldPostAccessibilityNotification()) { Position position = is<Text>(m_insertChild.get()) ? Position(downcast<Text>(m_insertChild.get()), 0) : createLegacyEditingPosition(m_insertChild.get(), 0); notifyAccessibilityForTextChange(m_insertChild.get(), applyEditType(), m_insertChild->nodeValue(), VisiblePosition(position)); } }
PassRefPtrWillBeRawPtr<Range> PlainTextRange::createRangeFor(const ContainerNode& scope, GetRangeFor getRangeFor) const { ASSERT(isNotNull()); RefPtrWillBeRawPtr<Range> resultRange = scope.document().createRange(); size_t docTextPosition = 0; bool startRangeFound = false; Position textRunStartPosition; Position textRunEndPosition; TextIteratorBehaviorFlags behaviorFlags = TextIteratorEmitsObjectReplacementCharacter; if (getRangeFor == ForSelection) behaviorFlags |= TextIteratorEmitsCharactersBetweenAllVisiblePositions; auto range = rangeOfContents(const_cast<ContainerNode*>(&scope)); TextIterator it(range->startPosition(), range->endPosition(), behaviorFlags); // FIXME: the atEnd() check shouldn't be necessary, workaround for <http://bugs.webkit.org/show_bug.cgi?id=6289>. if (!start() && !length() && it.atEnd()) { resultRange->setStart(it.currentContainer(), 0, ASSERT_NO_EXCEPTION); resultRange->setEnd(it.currentContainer(), 0, ASSERT_NO_EXCEPTION); return resultRange.release(); } for (; !it.atEnd(); it.advance()) { int len = it.length(); textRunStartPosition = it.startPositionInCurrentContainer(); textRunEndPosition = it.endPositionInCurrentContainer(); bool foundStart = start() >= docTextPosition && start() <= docTextPosition + len; bool foundEnd = end() >= docTextPosition && end() <= docTextPosition + len; // Fix textRunRange->endPosition(), but only if foundStart || foundEnd, because it is only // in those cases that textRunRange is used. if (foundEnd) { // FIXME: This is a workaround for the fact that the end of a run // is often at the wrong position for emitted '\n's or if the // renderer of the current node is a replaced element. if (len == 1 && (it.characterAt(0) == '\n' || it.isInsideReplacedElement())) { it.advance(); if (!it.atEnd()) { textRunEndPosition = it.startPositionInCurrentContainer(); } else { Position runEnd = VisiblePosition(textRunStartPosition).next().deepEquivalent(); if (runEnd.isNotNull()) textRunEndPosition = createLegacyEditingPosition(runEnd.containerNode(), runEnd.computeOffsetInContainerNode()); } } } if (foundStart) { startRangeFound = true; if (textRunStartPosition.containerNode()->isTextNode()) { int offset = start() - docTextPosition; resultRange->setStart(textRunStartPosition.containerNode(), offset + textRunStartPosition.offsetInContainerNode(), IGNORE_EXCEPTION); } else { if (start() == docTextPosition) resultRange->setStart(textRunStartPosition.containerNode(), textRunStartPosition.offsetInContainerNode(), IGNORE_EXCEPTION); else resultRange->setStart(textRunEndPosition.containerNode(), textRunEndPosition.offsetInContainerNode(), IGNORE_EXCEPTION); } } if (foundEnd) { if (textRunStartPosition.containerNode()->isTextNode()) { int offset = end() - docTextPosition; resultRange->setEnd(textRunStartPosition.containerNode(), offset + textRunStartPosition.offsetInContainerNode(), IGNORE_EXCEPTION); } else { if (end() == docTextPosition) resultRange->setEnd(textRunStartPosition.containerNode(), textRunStartPosition.offsetInContainerNode(), IGNORE_EXCEPTION); else resultRange->setEnd(textRunEndPosition.containerNode(), textRunEndPosition.offsetInContainerNode(), IGNORE_EXCEPTION); } docTextPosition += len; break; } docTextPosition += len; } if (!startRangeFound) return nullptr; if (length() && end() > docTextPosition) { // end() is out of bounds resultRange->setEnd(textRunEndPosition.containerNode(), textRunEndPosition.offsetInContainerNode(), IGNORE_EXCEPTION); } return resultRange.release(); }