// 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.offset(), end.offset() - start.offset(), text); Position endPosition(start.node(), start.offset() + 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> Selection forcedEndingSelection; forcedEndingSelection.setWithoutValidation(start, endPosition); setEndingSelection(forcedEndingSelection); if (!selectInsertedText) setEndingSelection(Selection(endingSelection().visibleEnd())); return true; }
bool InsertTextCommand::performOverwrite(const String& text, bool selectInsertedText) { Position start = endingSelection().start(); RefPtrWillBeRawPtr<Text> textNode = start.containerText(); if (!textNode) return false; unsigned count = std::min(text.length(), textNode->length() - start.offsetInContainerNode()); if (!count) return false; replaceTextInNode(textNode, start.offsetInContainerNode(), count, text); Position endPosition = Position(textNode.release(), start.offsetInContainerNode() + text.length()); setEndingSelectionWithoutValidation(start, endPosition); if (!selectInsertedText) setEndingSelection(VisibleSelection(endingSelection().visibleEnd(), endingSelection().isDirectional())); return true; }