#include "third_party/blink/renderer/core/editing/commands/composite_edit_command.h"
#include <algorithm>
#include "third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h"
#include "third_party/blink/renderer/core/accessibility/scoped_blink_ax_event_intent.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/document_fragment.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
#include "third_party/blink/renderer/core/dom/node_traversal.h"
#include "third_party/blink/renderer/core/dom/range.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/editing/commands/append_node_command.h"
#include "third_party/blink/renderer/core/editing/commands/apply_style_command.h"
#include "third_party/blink/renderer/core/editing/commands/delete_from_text_node_command.h"
#include "third_party/blink/renderer/core/editing/commands/delete_selection_command.h"
#include "third_party/blink/renderer/core/editing/commands/editing_commands_utilities.h"
#include "third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.h"
#include "third_party/blink/renderer/core/editing/commands/insert_line_break_command.h"
#include "third_party/blink/renderer/core/editing/commands/insert_node_before_command.h"
#include "third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.h"
#include "third_party/blink/renderer/core/editing/commands/merge_identical_elements_command.h"
#include "third_party/blink/renderer/core/editing/commands/remove_css_property_command.h"
#include "third_party/blink/renderer/core/editing/commands/remove_node_command.h"
#include "third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.h"
#include "third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.h"
#include "third_party/blink/renderer/core/editing/commands/replace_selection_command.h"
#include "third_party/blink/renderer/core/editing/commands/set_character_data_command.h"
#include "third_party/blink/renderer/core/editing/commands/set_node_attribute_command.h"
#include "third_party/blink/renderer/core/editing/commands/split_element_command.h"
#include "third_party/blink/renderer/core/editing/commands/split_text_node_command.h"
#include "third_party/blink/renderer/core/editing/commands/split_text_node_containing_element_command.h"
#include "third_party/blink/renderer/core/editing/commands/undo_stack.h"
#include "third_party/blink/renderer/core/editing/commands/wrap_contents_in_dummy_span_command.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/editor.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/iterators/text_iterator.h"
#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
#include "third_party/blink/renderer/core/editing/plain_text_range.h"
#include "third_party/blink/renderer/core/editing/relocatable_position.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/serializers/serialization.h"
#include "third_party/blink/renderer/core/editing/visible_position.h"
#include "third_party/blink/renderer/core/editing/visible_selection.h"
#include "third_party/blink/renderer/core/editing/visible_units.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/html_br_element.h"
#include "third_party/blink/renderer/core/html/html_div_element.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/html_li_element.h"
#include "third_party/blink/renderer/core/html/html_object_element.h"
#include "third_party/blink/renderer/core/html/html_olist_element.h"
#include "third_party/blink/renderer/core/html/html_quote_element.h"
#include "third_party/blink/renderer/core/html/html_span_element.h"
#include "third_party/blink/renderer/core/html/html_ulist_element.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/layout_text.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h"
namespace blink {
namespace {
bool IsWhitespaceForRebalance(const Text& text_node, UChar character) { … }
}
CompositeEditCommand::CompositeEditCommand(Document& document)
: … { … }
CompositeEditCommand::~CompositeEditCommand() { … }
VisibleSelection CompositeEditCommand::EndingVisibleSelection() const { … }
bool CompositeEditCommand::Apply() { … }
UndoStep* CompositeEditCommand::EnsureUndoStep() { … }
bool CompositeEditCommand::PreservesTypingStyle() const { … }
bool CompositeEditCommand::IsTypingCommand() const { … }
bool CompositeEditCommand::IsCommandGroupWrapper() const { … }
bool CompositeEditCommand::IsDragAndDropCommand() const { … }
bool CompositeEditCommand::IsReplaceSelectionCommand() const { … }
void CompositeEditCommand::ApplyCommandToComposite(
EditCommand* command,
EditingState* editing_state) { … }
void CompositeEditCommand::AppendCommandToUndoStep(
CompositeEditCommand* command) { … }
void CompositeEditCommand::ApplyStyle(const EditingStyle* style,
EditingState* editing_state) { … }
void CompositeEditCommand::ApplyStyle(const EditingStyle* style,
const Position& start,
const Position& end,
EditingState* editing_state) { … }
void CompositeEditCommand::ApplyStyledElement(Element* element,
EditingState* editing_state) { … }
void CompositeEditCommand::RemoveStyledElement(Element* element,
EditingState* editing_state) { … }
void CompositeEditCommand::InsertParagraphSeparator(
EditingState* editing_state,
bool use_default_paragraph_element,
bool paste_blockqutoe_into_unquoted_area) { … }
bool CompositeEditCommand::IsRemovableBlock(const Node* node) { … }
void CompositeEditCommand::InsertNodeBefore(
Node* insert_child,
Node* ref_child,
EditingState* editing_state,
ShouldAssumeContentIsAlwaysEditable
should_assume_content_is_always_editable) { … }
void CompositeEditCommand::InsertNodeAfter(Node* insert_child,
Node* ref_child,
EditingState* editing_state) { … }
void CompositeEditCommand::InsertNodeAt(Node* insert_child,
const Position& editing_position,
EditingState* editing_state) { … }
void CompositeEditCommand::AppendNode(Node* node,
ContainerNode* parent,
EditingState* editing_state) { … }
void CompositeEditCommand::RemoveAllChildrenIfPossible(
ContainerNode* container,
EditingState* editing_state,
ShouldAssumeContentIsAlwaysEditable
should_assume_content_is_always_editable) { … }
void CompositeEditCommand::RemoveChildrenInRange(Node* node,
unsigned from,
unsigned to,
EditingState* editing_state) { … }
void CompositeEditCommand::RemoveNode(
Node* node,
EditingState* editing_state,
ShouldAssumeContentIsAlwaysEditable
should_assume_content_is_always_editable) { … }
void CompositeEditCommand::RemoveNodePreservingChildren(
Node* node,
EditingState* editing_state,
ShouldAssumeContentIsAlwaysEditable
should_assume_content_is_always_editable) { … }
void CompositeEditCommand::RemoveNodeAndPruneAncestors(
Node* node,
EditingState* editing_state,
Node* exclude_node) { … }
void CompositeEditCommand::MoveRemainingSiblingsToNewParent(
Node* node,
Node* past_last_node_to_move,
Element* new_parent,
EditingState* editing_state) { … }
void CompositeEditCommand::UpdatePositionForNodeRemovalPreservingChildren(
Position& position,
Node& node) { … }
HTMLSpanElement*
CompositeEditCommand::ReplaceElementWithSpanPreservingChildrenAndAttributes(
HTMLElement* node) { … }
void CompositeEditCommand::Prune(Node* node,
EditingState* editing_state,
Node* exclude_node) { … }
void CompositeEditCommand::SplitTextNode(Text* node, unsigned offset) { … }
void CompositeEditCommand::SplitElement(Element* element, Node* at_child) { … }
void CompositeEditCommand::MergeIdenticalElements(Element* first,
Element* second,
EditingState* editing_state) { … }
void CompositeEditCommand::WrapContentsInDummySpan(Element* element) { … }
void CompositeEditCommand::SplitTextNodeContainingElement(Text* text,
unsigned offset) { … }
void CompositeEditCommand::InsertTextIntoNode(Text* node,
unsigned offset,
const String& text) { … }
void CompositeEditCommand::DeleteTextFromNode(Text* node,
unsigned offset,
unsigned count) { … }
void CompositeEditCommand::ReplaceTextInNode(Text* node,
unsigned offset,
unsigned count,
const String& replacement_text) { … }
Position CompositeEditCommand::ReplaceSelectedTextInNode(const String& text) { … }
Position CompositeEditCommand::PositionOutsideTabSpan(const Position& pos) { … }
void CompositeEditCommand::InsertNodeAtTabSpanPosition(
Node* node,
const Position& pos,
EditingState* editing_state) { … }
bool CompositeEditCommand::DeleteSelection(
EditingState* editing_state,
const DeleteSelectionOptions& options) { … }
void CompositeEditCommand::RemoveCSSProperty(Element* element,
CSSPropertyID property) { … }
void CompositeEditCommand::RemoveElementAttribute(
Element* element,
const QualifiedName& attribute) { … }
void CompositeEditCommand::SetNodeAttribute(Element* element,
const QualifiedName& attribute,
const AtomicString& value) { … }
bool CompositeEditCommand::CanRebalance(const Position& position) const { … }
void CompositeEditCommand::RebalanceWhitespaceAt(const Position& position) { … }
void CompositeEditCommand::RebalanceWhitespaceOnTextSubstring(Text* text_node,
int start_offset,
int end_offset) { … }
void CompositeEditCommand::PrepareWhitespaceAtPositionForSplit(
Position& position) { … }
void CompositeEditCommand::
ReplaceCollapsibleWhitespaceWithNonBreakingSpaceIfNeeded(
const VisiblePosition& visible_position) { … }
void CompositeEditCommand::RebalanceWhitespace() { … }
static bool IsInsignificantText(const LayoutText& layout_text) { … }
void CompositeEditCommand::DeleteInsignificantText(Text* text_node,
unsigned start,
unsigned end) { … }
void CompositeEditCommand::DeleteInsignificantText(const Position& start,
const Position& end) { … }
void CompositeEditCommand::DeleteInsignificantTextDownstream(
const Position& pos) { … }
HTMLBRElement* CompositeEditCommand::AppendBlockPlaceholder(
Element* container,
EditingState* editing_state) { … }
HTMLBRElement* CompositeEditCommand::InsertBlockPlaceholder(
const Position& pos,
EditingState* editing_state) { … }
static bool IsEmptyListItem(const LayoutBlockFlow& block_flow) { … }
HTMLBRElement* CompositeEditCommand::AddBlockPlaceholderIfNeeded(
Element* container,
EditingState* editing_state) { … }
void CompositeEditCommand::RemovePlaceholderAt(const Position& p) { … }
HTMLElement* CompositeEditCommand::InsertNewDefaultParagraphElementAt(
const Position& position,
EditingState* editing_state) { … }
HTMLElement* CompositeEditCommand::MoveParagraphContentsToNewBlockIfNecessary(
const Position& pos,
EditingState* editing_state) { … }
void CompositeEditCommand::PushAnchorElementDown(Element* anchor_node,
EditingState* editing_state) { … }
void CompositeEditCommand::CloneParagraphUnderNewElement(
const Position& start,
const Position& end,
Node* passed_outer_node,
Element* block_element,
EditingState* editing_state) { … }
void CompositeEditCommand::CleanupAfterDeletion(EditingState* editing_state) { … }
void CompositeEditCommand::CleanupAfterDeletion(EditingState* editing_state,
VisiblePosition destination) { … }
void CompositeEditCommand::MoveParagraphWithClones(
const VisiblePosition& start_of_paragraph_to_move,
const VisiblePosition& end_of_paragraph_to_move,
HTMLElement* block_element,
Node* outer_node,
EditingState* editing_state) { … }
void CompositeEditCommand::MoveParagraph(
const VisiblePosition& start_of_paragraph_to_move,
const VisiblePosition& end_of_paragraph_to_move,
const VisiblePosition& destination,
EditingState* editing_state,
ShouldPreserveSelection should_preserve_selection,
ShouldPreserveStyle should_preserve_style,
Node* constraining_ancestor) { … }
void CompositeEditCommand::MoveParagraphs(
const VisiblePosition& start_of_paragraph_to_move,
const VisiblePosition& end_of_paragraph_to_move,
const VisiblePosition& destination,
EditingState* editing_state,
ShouldPreserveSelection should_preserve_selection,
ShouldPreserveStyle should_preserve_style,
Node* constraining_ancestor) { … }
bool CompositeEditCommand::BreakOutOfEmptyListItem(
EditingState* editing_state) { … }
bool CompositeEditCommand::BreakOutOfEmptyMailBlockquotedParagraph(
EditingState* editing_state) { … }
Position CompositeEditCommand::PositionAvoidingSpecialElementBoundary(
const Position& original,
EditingState* editing_state) { … }
Node* CompositeEditCommand::SplitTreeToNode(Node* start,
Node* end,
bool should_split_ancestor) { … }
void CompositeEditCommand::SetStartingSelection(
const SelectionForUndoStep& selection) { … }
void CompositeEditCommand::SetEndingSelection(
const SelectionForUndoStep& selection) { … }
void CompositeEditCommand::SetParent(CompositeEditCommand* parent) { … }
bool CompositeEditCommand::IsNodeVisiblyContainedWithin(
Node& node,
const EphemeralRange& selected_range) { … }
void CompositeEditCommand::Trace(Visitor* visitor) const { … }
void CompositeEditCommand::AppliedEditing() { … }
}