本文整理汇总了C++中VisibleSelection::setWithoutValidation方法的典型用法代码示例。如果您正苦于以下问题:C++ VisibleSelection::setWithoutValidation方法的具体用法?C++ VisibleSelection::setWithoutValidation怎么用?C++ VisibleSelection::setWithoutValidation使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类VisibleSelection
的用法示例。
在下文中一共展示了VisibleSelection::setWithoutValidation方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: performTrivialReplace
// This avoids the expense of a full fledged delete operation, and avoids a layout that typically results
// from text removal.
bool InsertTextCommand::performTrivialReplace(const String& text, bool selectInsertedText)
{
if (!endingSelection().isRange())
return false;
if (text.contains('\t') || text.contains(' ') || text.contains('\n'))
return false;
Position start = endingSelection().start();
Position endPosition = replaceSelectedTextInNode(text);
if (endPosition.isNull())
return false;
// We could have inserted a part of composed character sequence,
// so we are basically treating ending selection as a range to avoid validation.
// <http://bugs.webkit.org/show_bug.cgi?id=15781>
VisibleSelection forcedEndingSelection;
forcedEndingSelection.setWithoutValidation(start, endPosition);
forcedEndingSelection.setIsDirectional(endingSelection().isDirectional());
setEndingSelection(forcedEndingSelection);
if (!selectInsertedText)
setEndingSelection(VisibleSelection(endingSelection().visibleEnd(), endingSelection().isDirectional()));
return true;
}
示例2: calcVisibleSelectionAlgorithm
VisibleSelection PendingSelection::calcVisibleSelectionAlgorithm() const
{
using PositionType = typename Strategy::PositionType;
PositionType start = Strategy::selectionStart(m_selection);
PositionType end = Strategy::selectionEnd(m_selection);
SelectionType selectionType = VisibleSelection::selectionType(start, end);
TextAffinity affinity = m_selection.affinity();
bool paintBlockCursor = m_shouldShowBlockCursor && selectionType == SelectionType::CaretSelection && !isLogicalEndOfLine(VisiblePosition(end, affinity));
VisibleSelection selection;
if (enclosingTextFormControl(start.computeContainerNode())) {
// TODO(yosin) We should use |PositionMoveType::Character| to avoid
// ending paint at middle of character.
PositionType endPosition = paintBlockCursor ? nextPositionOf(Strategy::selectionExtent(m_selection), PositionMoveType::CodePoint) : end;
selection.setWithoutValidation(start, endPosition);
return selection;
}
VisiblePosition visibleStart = VisiblePosition(start, selectionType == SelectionType::RangeSelection ? TextAffinity::Downstream : affinity);
if (paintBlockCursor) {
VisiblePosition visibleExtent(end, affinity);
visibleExtent = visibleExtent.next(CanSkipOverEditingBoundary);
return VisibleSelection(visibleStart, visibleExtent);
}
VisiblePosition visibleEnd(end, selectionType == SelectionType::RangeSelection ? TextAffinity::Upstream : affinity);
return VisibleSelection(visibleStart, visibleEnd);
}
示例3: performTrivialReplace
// This avoids the expense of a full fledged delete operation, and avoids a layout that typically results
// from text removal.
bool InsertTextCommand::performTrivialReplace(const String& text, bool selectInsertedText)
{
if (!endingSelection().isRange())
return false;
if (text.contains('\t') || text.contains(' ') || text.contains('\n'))
return false;
Position start = endingSelection().start();
Position end = endingSelection().end();
if (start.node() != end.node() || !start.node()->isTextNode() || isTabSpanTextNode(start.node()))
return false;
replaceTextInNode(static_cast<Text*>(start.node()), start.deprecatedEditingOffset(), end.deprecatedEditingOffset() - start.deprecatedEditingOffset(), text);
Position endPosition(start.node(), start.deprecatedEditingOffset() + text.length());
// We could have inserted a part of composed character sequence,
// so we are basically treating ending selection as a range to avoid validation.
// <http://bugs.webkit.org/show_bug.cgi?id=15781>
VisibleSelection forcedEndingSelection;
forcedEndingSelection.setWithoutValidation(start, endPosition);
setEndingSelection(forcedEndingSelection);
if (!selectInsertedText)
setEndingSelection(VisibleSelection(endingSelection().visibleEnd()));
return true;
}
示例4: setSelectionRange
void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextFieldSelectionDirection direction, NeedToDispatchSelectEvent eventBehaviour, SelectionOption selectionOption)
{
if (openShadowRoot() || !isTextFormControl())
return;
const int editorValueLength = static_cast<int>(innerEditorValue().length());
ASSERT(editorValueLength >= 0);
end = std::max(std::min(end, editorValueLength), 0);
start = std::min(std::max(start, 0), end);
cacheSelection(start, end, direction);
if (selectionOption == NotChangeSelection || (selectionOption == ChangeSelectionIfFocused && document().focusedElement() != this) || !inShadowIncludingDocument()) {
if (eventBehaviour == DispatchSelectEvent)
scheduleSelectEvent();
return;
}
LocalFrame* frame = document().frame();
HTMLElement* innerEditor = innerEditorElement();
if (!frame || !innerEditor)
return;
Position startPosition = positionForIndex(innerEditor, start);
Position endPosition = start == end ? startPosition : positionForIndex(innerEditor, end);
ASSERT(start == indexForPosition(innerEditor, startPosition));
ASSERT(end == indexForPosition(innerEditor, endPosition));
#if ENABLE(ASSERT)
// startPosition and endPosition can be null position for example when
// "-webkit-user-select: none" style attribute is specified.
if (startPosition.isNotNull() && endPosition.isNotNull()) {
ASSERT(startPosition.anchorNode()->shadowHost() == this
&& endPosition.anchorNode()->shadowHost() == this);
}
#endif // ENABLE(ASSERT)
VisibleSelection newSelection;
if (direction == SelectionHasBackwardDirection)
newSelection.setWithoutValidation(endPosition, startPosition);
else
newSelection.setWithoutValidation(startPosition, endPosition);
newSelection.setIsDirectional(direction != SelectionHasNoDirection);
frame->selection().setSelection(newSelection, FrameSelection::DoNotAdjustInFlatTree | FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | (selectionOption == ChangeSelectionAndFocus ? 0 : FrameSelection::DoNotSetFocus));
if (eventBehaviour == DispatchSelectEvent)
scheduleSelectEvent();
}
示例5: setEndingSelectionWithoutValidation
void InsertTextCommand::setEndingSelectionWithoutValidation(const Position& startPosition, const Position& endPosition)
{
// We could have inserted a part of composed character sequence,
// so we are basically treating ending selection as a range to avoid validation.
// <http://bugs.webkit.org/show_bug.cgi?id=15781>
VisibleSelection forcedEndingSelection;
forcedEndingSelection.setWithoutValidation(startPosition, endPosition);
forcedEndingSelection.setIsDirectional(endingSelection().isDirectional());
setEndingSelection(forcedEndingSelection);
}
示例6: selectComposition
void InputMethodController::selectComposition() const
{
RefPtr<Range> range = compositionRange();
if (!range)
return;
// The composition can start inside a composed character sequence, so we have to override checks.
// See <http://bugs.webkit.org/show_bug.cgi?id=15781>
VisibleSelection selection;
selection.setWithoutValidation(range->startPosition(), range->endPosition());
m_frame->selection().setSelection(selection, 0);
}
示例7: selectComposition
void InputMethodController::selectComposition() const
{
const EphemeralRange range = compositionEphemeralRange();
if (range.isNull())
return;
// The composition can start inside a composed character sequence, so we have to override checks.
// See <http://bugs.webkit.org/show_bug.cgi?id=15781>
VisibleSelection selection;
selection.setWithoutValidation(range.startPosition(), range.endPosition());
frame().selection().setSelection(selection, 0);
}
示例8: Position
TEST_F(FrameSelectionTest, SetInvalidSelection)
{
// Create a new document without frame by using DOMImplementation.
DocumentInit dummy;
RefPtrWillBeRawPtr<Document> documentWithoutFrame = Document::create();
RefPtrWillBeRawPtr<Element> body = documentWithoutFrame->createElement(HTMLNames::bodyTag, false);
documentWithoutFrame->appendChild(body);
RefPtrWillBeRawPtr<Text> anotherText = documentWithoutFrame->createTextNode("Hello, another world");
body->appendChild(anotherText);
// Create a new VisibleSelection for the new document without frame and
// update FrameSelection with the selection.
VisibleSelection invalidSelection;
invalidSelection.setWithoutValidation(Position(anotherText, 0), Position(anotherText, 5));
setSelection(invalidSelection);
EXPECT_TRUE(selection().isNone());
}
示例9: forwardDeleteKeyPressed
void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool killRing)
{
Frame* frame = document()->frame();
if (!frame)
return;
frame->editor()->updateMarkersForWordsAffectedByEditing(false);
VisibleSelection selectionToDelete;
VisibleSelection selectionAfterUndo;
switch (endingSelection().selectionType()) {
case VisibleSelection::RangeSelection:
selectionToDelete = endingSelection();
selectionAfterUndo = selectionToDelete;
break;
case VisibleSelection::CaretSelection: {
m_smartDelete = false;
// Handle delete at beginning-of-block case.
// Do nothing in the case that the caret is at the start of a
// root editable element or at the start of a document.
FrameSelection selection;
selection.setSelection(endingSelection());
selection.modify(FrameSelection::AlterationExtend, DirectionForward, granularity);
if (killRing && selection.isCaret() && granularity != CharacterGranularity)
selection.modify(FrameSelection::AlterationExtend, DirectionForward, CharacterGranularity);
Position downstreamEnd = endingSelection().end().downstream();
VisiblePosition visibleEnd = endingSelection().visibleEnd();
Node* enclosingTableCell = enclosingNodeOfType(visibleEnd.deepEquivalent(), &isTableCell);
if (enclosingTableCell && visibleEnd == lastPositionInNode(enclosingTableCell))
return;
if (visibleEnd == endOfParagraph(visibleEnd))
downstreamEnd = visibleEnd.next(CannotCrossEditingBoundary).deepEquivalent().downstream();
// When deleting tables: Select the table first, then perform the deletion
if (downstreamEnd.containerNode() && downstreamEnd.containerNode()->renderer() && downstreamEnd.containerNode()->renderer()->isTable()
&& downstreamEnd.computeOffsetInContainerNode() <= caretMinOffset(downstreamEnd.containerNode())) {
setEndingSelection(VisibleSelection(endingSelection().end(), positionAfterNode(downstreamEnd.containerNode()), DOWNSTREAM, endingSelection().isDirectional()));
typingAddedToOpenCommand(ForwardDeleteKey);
return;
}
// deleting to end of paragraph when at end of paragraph needs to merge the next paragraph (if any)
if (granularity == ParagraphBoundary && selection.selection().isCaret() && isEndOfParagraph(selection.selection().visibleEnd()))
selection.modify(FrameSelection::AlterationExtend, DirectionForward, CharacterGranularity);
selectionToDelete = selection.selection();
if (!startingSelection().isRange() || selectionToDelete.base() != startingSelection().start())
selectionAfterUndo = selectionToDelete;
else {
// It's a little tricky to compute what the starting selection would have been in the original document.
// We can't let the VisibleSelection class's validation kick in or it'll adjust for us based on
// the current state of the document and we'll get the wrong result.
Position extent = startingSelection().end();
if (extent.containerNode() != selectionToDelete.end().containerNode())
extent = selectionToDelete.extent();
else {
int extraCharacters;
if (selectionToDelete.start().containerNode() == selectionToDelete.end().containerNode())
extraCharacters = selectionToDelete.end().computeOffsetInContainerNode() - selectionToDelete.start().computeOffsetInContainerNode();
else
extraCharacters = selectionToDelete.end().computeOffsetInContainerNode();
extent = Position(extent.containerNode(), extent.computeOffsetInContainerNode() + extraCharacters, Position::PositionIsOffsetInAnchor);
}
selectionAfterUndo.setWithoutValidation(startingSelection().start(), extent);
}
break;
}
case VisibleSelection::NoSelection:
ASSERT_NOT_REACHED();
break;
}
ASSERT(!selectionToDelete.isNone());
if (selectionToDelete.isNone())
return;
if (selectionToDelete.isCaret() || !frame->selection()->shouldDeleteSelection(selectionToDelete))
return;
if (killRing)
frame->editor()->addToKillRing(selectionToDelete.toNormalizedRange().get(), false);
// make undo select what was deleted
setStartingSelection(selectionAfterUndo);
CompositeEditCommand::deleteSelection(selectionToDelete, m_smartDelete);
setSmartDelete(false);
typingAddedToOpenCommand(ForwardDeleteKey);
}
示例10: deleteKeyPressed
void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool killRing)
{
Frame* frame = document()->frame();
if (!frame)
return;
frame->editor()->updateMarkersForWordsAffectedByEditing(false);
VisibleSelection selectionToDelete;
VisibleSelection selectionAfterUndo;
switch (endingSelection().selectionType()) {
case VisibleSelection::RangeSelection:
selectionToDelete = endingSelection();
selectionAfterUndo = selectionToDelete;
break;
case VisibleSelection::CaretSelection: {
// After breaking out of an empty mail blockquote, we still want continue with the deletion
// so actual content will get deleted, and not just the quote style.
if (breakOutOfEmptyMailBlockquotedParagraph())
typingAddedToOpenCommand(DeleteKey);
m_smartDelete = false;
FrameSelection selection;
selection.setSelection(endingSelection());
selection.modify(FrameSelection::AlterationExtend, DirectionBackward, granularity);
if (killRing && selection.isCaret() && granularity != CharacterGranularity)
selection.modify(FrameSelection::AlterationExtend, DirectionBackward, CharacterGranularity);
if (endingSelection().visibleStart().previous(CannotCrossEditingBoundary).isNull()) {
// When the caret is at the start of the editable area in an empty list item, break out of the list item.
if (breakOutOfEmptyListItem()) {
typingAddedToOpenCommand(DeleteKey);
return;
}
// When there are no visible positions in the editing root, delete its entire contents.
if (endingSelection().visibleStart().next(CannotCrossEditingBoundary).isNull() && makeEditableRootEmpty()) {
typingAddedToOpenCommand(DeleteKey);
return;
}
}
VisiblePosition visibleStart(endingSelection().visibleStart());
// If we have a caret selection at the beginning of a cell, we have nothing to do.
Node* enclosingTableCell = enclosingNodeOfType(visibleStart.deepEquivalent(), &isTableCell);
if (enclosingTableCell && visibleStart == firstPositionInNode(enclosingTableCell))
return;
// If the caret is at the start of a paragraph after a table, move content into the last table cell.
if (isStartOfParagraph(visibleStart) && isFirstPositionAfterTable(visibleStart.previous(CannotCrossEditingBoundary))) {
// Unless the caret is just before a table. We don't want to move a table into the last table cell.
if (isLastPositionBeforeTable(visibleStart))
return;
// Extend the selection backward into the last cell, then deletion will handle the move.
selection.modify(FrameSelection::AlterationExtend, DirectionBackward, granularity);
// If the caret is just after a table, select the table and don't delete anything.
} else if (Node* table = isFirstPositionAfterTable(visibleStart)) {
setEndingSelection(VisibleSelection(positionBeforeNode(table), endingSelection().start(), DOWNSTREAM, endingSelection().isDirectional()));
typingAddedToOpenCommand(DeleteKey);
return;
}
selectionToDelete = selection.selection();
if (granularity == CharacterGranularity && selectionToDelete.end().containerNode() == selectionToDelete.start().containerNode()
&& selectionToDelete.end().computeOffsetInContainerNode() - selectionToDelete.start().computeOffsetInContainerNode() > 1) {
// If there are multiple Unicode code points to be deleted, adjust the range to match platform conventions.
selectionToDelete.setWithoutValidation(selectionToDelete.end(), selectionToDelete.end().previous(BackwardDeletion));
}
if (!startingSelection().isRange() || selectionToDelete.base() != startingSelection().start())
selectionAfterUndo = selectionToDelete;
else
// It's a little tricky to compute what the starting selection would have been in the original document.
// We can't let the VisibleSelection class's validation kick in or it'll adjust for us based on
// the current state of the document and we'll get the wrong result.
selectionAfterUndo.setWithoutValidation(startingSelection().end(), selectionToDelete.extent());
break;
}
case VisibleSelection::NoSelection:
ASSERT_NOT_REACHED();
break;
}
ASSERT(!selectionToDelete.isNone());
if (selectionToDelete.isNone())
return;
if (selectionToDelete.isCaret() || !frame->selection()->shouldDeleteSelection(selectionToDelete))
return;
if (killRing)
frame->editor()->addToKillRing(selectionToDelete.toNormalizedRange().get(), false);
// Make undo select everything that has been deleted, unless an undo will undo more than just this deletion.
// FIXME: This behaves like TextEdit except for the case where you open with text insertion and then delete
// more text than you insert. In that case all of the text that was around originally should be selected.
if (m_openedByBackwardDelete)
setStartingSelection(selectionAfterUndo);
CompositeEditCommand::deleteSelection(selectionToDelete, m_smartDelete);
//.........这里部分代码省略.........
示例11: forwardDeleteKeyPressed
void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool killRing)
{
VisibleSelection selectionToDelete;
VisibleSelection selectionAfterUndo;
switch (endingSelection().selectionType()) {
case VisibleSelection::RangeSelection:
selectionToDelete = endingSelection();
selectionAfterUndo = selectionToDelete;
break;
case VisibleSelection::CaretSelection: {
m_smartDelete = false;
// Handle delete at beginning-of-block case.
// Do nothing in the case that the caret is at the start of a
// root editable element or at the start of a document.
SelectionController selection;
selection.setSelection(endingSelection());
selection.modify(SelectionController::EXTEND, SelectionController::FORWARD, granularity);
if (killRing && selection.isCaret() && granularity != CharacterGranularity)
selection.modify(SelectionController::EXTEND, SelectionController::FORWARD, CharacterGranularity);
Position downstreamEnd = endingSelection().end().downstream();
VisiblePosition visibleEnd = endingSelection().visibleEnd();
if (visibleEnd == endOfParagraph(visibleEnd))
downstreamEnd = visibleEnd.next(true).deepEquivalent().downstream();
// When deleting tables: Select the table first, then perform the deletion
if (downstreamEnd.node() && downstreamEnd.node()->renderer() && downstreamEnd.node()->renderer()->isTable() && downstreamEnd.deprecatedEditingOffset() == 0) {
setEndingSelection(VisibleSelection(endingSelection().end(), lastDeepEditingPositionForNode(downstreamEnd.node()), DOWNSTREAM));
typingAddedToOpenCommand(ForwardDeleteKey);
return;
}
// deleting to end of paragraph when at end of paragraph needs to merge the next paragraph (if any)
if (granularity == ParagraphBoundary && selection.selection().isCaret() && isEndOfParagraph(selection.selection().visibleEnd()))
selection.modify(SelectionController::EXTEND, SelectionController::FORWARD, CharacterGranularity);
selectionToDelete = selection.selection();
if (!startingSelection().isRange() || selectionToDelete.base() != startingSelection().start())
selectionAfterUndo = selectionToDelete;
else {
// It's a little tricky to compute what the starting selection would have been in the original document.
// We can't let the VisibleSelection class's validation kick in or it'll adjust for us based on
// the current state of the document and we'll get the wrong result.
Position extent = startingSelection().end();
if (extent.node() != selectionToDelete.end().node())
extent = selectionToDelete.extent();
else {
int extraCharacters;
if (selectionToDelete.start().node() == selectionToDelete.end().node())
extraCharacters = selectionToDelete.end().deprecatedEditingOffset() - selectionToDelete.start().deprecatedEditingOffset();
else
extraCharacters = selectionToDelete.end().deprecatedEditingOffset();
extent = Position(extent.node(), extent.deprecatedEditingOffset() + extraCharacters);
}
selectionAfterUndo.setWithoutValidation(startingSelection().start(), extent);
}
break;
}
case VisibleSelection::NoSelection:
ASSERT_NOT_REACHED();
break;
}
ASSERT(!selectionToDelete.isNone());
if (selectionToDelete.isNone())
return;
if (selectionToDelete.isCaret() || !document()->frame()->shouldDeleteSelection(selectionToDelete))
return;
if (killRing)
document()->frame()->editor()->addToKillRing(selectionToDelete.toNormalizedRange().get(), false);
// make undo select what was deleted
setStartingSelection(selectionAfterUndo);
CompositeEditCommand::deleteSelection(selectionToDelete, m_smartDelete);
setSmartDelete(false);
typingAddedToOpenCommand(ForwardDeleteKey);
}
示例12: doApply
void InsertTextCommand::doApply()
{
ASSERT(m_text.find('\n') == notFound);
if (!endingSelection().isNonOrphanedCaretOrRange())
return;
// Delete the current selection.
// FIXME: This delete operation blows away the typing style.
if (endingSelection().isRange()) {
if (performTrivialReplace(m_text, m_selectInsertedText))
return;
deleteSelection(false, true, true, false, false);
// deleteSelection eventually makes a new endingSelection out of a Position. If that Position doesn't have
// a renderer (e.g. it is on a <frameset> in the DOM), the VisibleSelection cannot be canonicalized to
// anything other than NoSelection. The rest of this function requires a real endingSelection, so bail out.
if (endingSelection().isNone())
return;
}
Position startPosition(endingSelection().start());
Position placeholder;
// We want to remove preserved newlines and brs that will collapse (and thus become unnecessary) when content
// is inserted just before them.
// FIXME: We shouldn't really have to do this, but removing placeholders is a workaround for 9661.
// If the caret is just before a placeholder, downstream will normalize the caret to it.
Position downstream(startPosition.downstream());
if (lineBreakExistsAtPosition(downstream)) {
// FIXME: This doesn't handle placeholders at the end of anonymous blocks.
VisiblePosition caret(startPosition);
if (isEndOfBlock(caret) && isStartOfParagraph(caret))
placeholder = downstream;
// Don't remove the placeholder yet, otherwise the block we're inserting into would collapse before
// we get a chance to insert into it. We check for a placeholder now, though, because doing so requires
// the creation of a VisiblePosition, and if we did that post-insertion it would force a layout.
}
// Insert the character at the leftmost candidate.
startPosition = startPosition.upstream();
// It is possible for the node that contains startPosition to contain only unrendered whitespace,
// and so deleteInsignificantText could remove it. Save the position before the node in case that happens.
Position positionBeforeStartNode(positionInParentBeforeNode(startPosition.containerNode()));
deleteInsignificantText(startPosition.upstream(), startPosition.downstream());
if (!startPosition.anchorNode()->inDocument())
startPosition = positionBeforeStartNode;
if (!startPosition.isCandidate())
startPosition = startPosition.downstream();
startPosition = positionAvoidingSpecialElementBoundary(startPosition);
Position endPosition;
if (m_text == "\t") {
endPosition = insertTab(startPosition);
startPosition = endPosition.previous();
if (placeholder.isNotNull())
removePlaceholderAt(placeholder);
} else {
// Make sure the document is set up to receive m_text
startPosition = positionInsideTextNode(startPosition);
ASSERT(startPosition.anchorType() == Position::PositionIsOffsetInAnchor);
ASSERT(startPosition.containerNode());
ASSERT(startPosition.containerNode()->isTextNode());
if (placeholder.isNotNull())
removePlaceholderAt(placeholder);
RefPtr<Text> textNode = startPosition.containerText();
const unsigned offset = startPosition.offsetInContainerNode();
insertTextIntoNode(textNode, offset, m_text);
endPosition = Position(textNode, offset + m_text.length());
if (m_markerSupplier)
m_markerSupplier->addMarkersToTextNode(textNode.get(), offset, m_text);
if (m_rebalanceType == RebalanceLeadingAndTrailingWhitespaces) {
// The insertion may require adjusting adjacent whitespace, if it is present.
rebalanceWhitespaceAt(endPosition);
// Rebalancing on both sides isn't necessary if we've inserted only spaces.
if (!shouldRebalanceLeadingWhitespaceFor(m_text))
rebalanceWhitespaceAt(startPosition);
} else {
ASSERT(m_rebalanceType == RebalanceAllWhitespaces);
if (canRebalance(startPosition) && canRebalance(endPosition))
rebalanceWhitespaceOnTextSubstring(textNode, startPosition.offsetInContainerNode(), endPosition.offsetInContainerNode());
}
}
// We could have inserted a part of composed character sequence,
// so we are basically treating ending selection as a range to avoid validation.
// <http://bugs.webkit.org/show_bug.cgi?id=15781>
VisibleSelection forcedEndingSelection;
forcedEndingSelection.setWithoutValidation(startPosition, endPosition);
forcedEndingSelection.setIsDirectional(endingSelection().isDirectional());
setEndingSelection(forcedEndingSelection);
// Handle the case where there is a typing style.
if (RefPtr<EditingStyle> typingStyle = document()->frame()->selection()->typingStyle()) {
typingStyle->prepareToApplyAt(endPosition, EditingStyle::PreserveWritingDirection);
if (!typingStyle->isEmpty())
//.........这里部分代码省略.........
示例13: input
void InsertTextCommand::input(const String& text, bool selectInsertedText)
{
ASSERT(text.find('\n') == notFound);
if (!endingSelection().isNonOrphanedCaretOrRange())
return;
// Delete the current selection.
// FIXME: This delete operation blows away the typing style.
if (endingSelection().isRange()) {
if (performTrivialReplace(text, selectInsertedText))
return;
deleteSelection(false, true, true, false);
}
Position startPosition(endingSelection().start());
Position placeholder;
// We want to remove preserved newlines and brs that will collapse (and thus become unnecessary) when content
// is inserted just before them.
// FIXME: We shouldn't really have to do this, but removing placeholders is a workaround for 9661.
// If the caret is just before a placeholder, downstream will normalize the caret to it.
Position downstream(startPosition.downstream());
if (lineBreakExistsAtPosition(downstream)) {
// FIXME: This doesn't handle placeholders at the end of anonymous blocks.
VisiblePosition caret(startPosition);
if (isEndOfBlock(caret) && isStartOfParagraph(caret))
placeholder = downstream;
// Don't remove the placeholder yet, otherwise the block we're inserting into would collapse before
// we get a chance to insert into it. We check for a placeholder now, though, because doing so requires
// the creation of a VisiblePosition, and if we did that post-insertion it would force a layout.
}
// Insert the character at the leftmost candidate.
startPosition = startPosition.upstream();
// It is possible for the node that contains startPosition to contain only unrendered whitespace,
// and so deleteInsignificantText could remove it. Save the position before the node in case that happens.
Position positionBeforeStartNode(positionInParentBeforeNode(startPosition.node()));
deleteInsignificantText(startPosition.upstream(), startPosition.downstream());
if (!startPosition.node()->inDocument())
startPosition = positionBeforeStartNode;
if (!startPosition.isCandidate())
startPosition = startPosition.downstream();
startPosition = positionAvoidingSpecialElementBoundary(startPosition);
Position endPosition;
if (text == "\t") {
endPosition = insertTab(startPosition);
startPosition = endPosition.previous();
if (placeholder.isNotNull())
removePlaceholderAt(placeholder);
m_charactersAdded += 1;
} else {
// Make sure the document is set up to receive text
startPosition = prepareForTextInsertion(startPosition);
if (placeholder.isNotNull())
removePlaceholderAt(placeholder);
Text *textNode = static_cast<Text *>(startPosition.node());
int offset = startPosition.deprecatedEditingOffset();
insertTextIntoNode(textNode, offset, text);
endPosition = Position(textNode, offset + text.length());
// The insertion may require adjusting adjacent whitespace, if it is present.
rebalanceWhitespaceAt(endPosition);
// Rebalancing on both sides isn't necessary if we've inserted a space.
if (text != " ")
rebalanceWhitespaceAt(startPosition);
m_charactersAdded += text.length();
}
// We could have inserted a part of composed character sequence,
// so we are basically treating ending selection as a range to avoid validation.
// <http://bugs.webkit.org/show_bug.cgi?id=15781>
VisibleSelection forcedEndingSelection;
forcedEndingSelection.setWithoutValidation(startPosition, endPosition);
setEndingSelection(forcedEndingSelection);
// Handle the case where there is a typing style.
CSSMutableStyleDeclaration* typingStyle = document()->frame()->selection()->typingStyle();
RefPtr<CSSComputedStyleDeclaration> endingStyle = endPosition.computedStyle();
RefPtr<CSSValue> unicodeBidi;
RefPtr<CSSValue> direction;
if (typingStyle) {
unicodeBidi = typingStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
direction = typingStyle->getPropertyCSSValue(CSSPropertyDirection);
}
endingStyle->diff(typingStyle);
if (typingStyle && unicodeBidi) {
ASSERT(unicodeBidi->isPrimitiveValue());
typingStyle->setProperty(CSSPropertyUnicodeBidi, static_cast<CSSPrimitiveValue*>(unicodeBidi.get())->getIdent());
if (direction) {
ASSERT(direction->isPrimitiveValue());
typingStyle->setProperty(CSSPropertyDirection, static_cast<CSSPrimitiveValue*>(direction.get())->getIdent());
}
//.........这里部分代码省略.........