String CreateMarkupAlgorithm<Strategy>::createMarkup( const PositionTemplate<Strategy>& startPosition, const PositionTemplate<Strategy>& endPosition, EAnnotateForInterchange shouldAnnotate, ConvertBlocksToInlines convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs, Node* constrainingAncestor) { if (startPosition.isNull() || endPosition.isNull()) return emptyString(); RELEASE_ASSERT(startPosition.compareTo(endPosition) <= 0); bool collapsed = startPosition == endPosition; if (collapsed) return emptyString(); Node* commonAncestor = Strategy::commonAncestor(*startPosition.computeContainerNode(), *endPosition.computeContainerNode()); if (!commonAncestor) return emptyString(); Document* document = startPosition.document(); DCHECK(!document->needsLayoutTreeUpdate()); DocumentLifecycle::DisallowTransitionScope disallowTransition( document->lifecycle()); HTMLElement* specialCommonAncestor = highestAncestorToWrapMarkup<Strategy>( startPosition, endPosition, shouldAnnotate, constrainingAncestor); StyledMarkupSerializer<Strategy> serializer( shouldResolveURLs, shouldAnnotate, startPosition, endPosition, specialCommonAncestor, convertBlocksToInlines); return serializer.createMarkup(); }
VisibleSelectionTemplate<Strategy> PendingSelection::calcVisibleSelectionAlgorithm(const VisibleSelectionTemplate<Strategy>& originalSelection) const { const PositionTemplate<Strategy> start = originalSelection.start(); const PositionTemplate<Strategy> end = originalSelection.end(); SelectionType selectionType = originalSelection.selectionType(); const TextAffinity affinity = originalSelection.affinity(); bool paintBlockCursor = m_frameSelection->shouldShowBlockCursor() && selectionType == SelectionType::CaretSelection && !isLogicalEndOfLine(createVisiblePosition(end, affinity)); VisibleSelectionTemplate<Strategy> selection; if (enclosingTextFormControl(start.computeContainerNode())) { // TODO(yosin) We should use |PositionMoveType::Character| to avoid // ending paint at middle of character. PositionTemplate<Strategy> endPosition = paintBlockCursor ? nextPositionOf(originalSelection.extent(), PositionMoveType::CodePoint) : end; selection.setWithoutValidation(start, endPosition); return selection; } const VisiblePositionTemplate<Strategy> visibleStart = createVisiblePosition(start, selectionType == SelectionType::RangeSelection ? TextAffinity::Downstream : affinity); if (paintBlockCursor) { VisiblePositionTemplate<Strategy> visibleExtent = createVisiblePosition(end, affinity); visibleExtent = nextPositionOf(visibleExtent, CanSkipOverEditingBoundary); return VisibleSelectionTemplate<Strategy>(visibleStart, visibleExtent); } const VisiblePositionTemplate<Strategy> visibleEnd = createVisiblePosition(end, selectionType == SelectionType::RangeSelection ? TextAffinity::Upstream : affinity); return VisibleSelectionTemplate<Strategy>(visibleStart, visibleEnd); }
EphemeralRangeTemplate<Strategy> CharacterIteratorAlgorithm<Strategy>::range() const { EphemeralRangeTemplate<Strategy> range(m_textIterator.range()); if (m_textIterator.atEnd() || m_textIterator.length() <= 1) return range; PositionTemplate<Strategy> startPosition = range.startPosition().parentAnchoredEquivalent(); PositionTemplate<Strategy> endPosition = range.endPosition().parentAnchoredEquivalent(); Node* node = startPosition.computeContainerNode(); DCHECK_EQ(node, endPosition.computeContainerNode()); int offset = startPosition.offsetInContainerNode() + m_runOffset; return EphemeralRangeTemplate<Strategy>( PositionTemplate<Strategy>(node, offset), PositionTemplate<Strategy>(node, offset + 1)); }