chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc

/*
 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#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) {}

}  // namespace

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 {}

//
// sugary-sweet convenience functions to help create and apply edit commands in
// composite commands
//
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 {}

// FIXME: Doesn't go into text nodes that contribute adjacent text (siblings,
// cousins, etc).
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) {}

// Assumes that the position is at a placeholder and does the removal without
// much checking.
void CompositeEditCommand::RemovePlaceholderAt(const Position& p) {}

HTMLElement* CompositeEditCommand::InsertNewDefaultParagraphElementAt(
    const Position& position,
    EditingState* editing_state) {}

// If the paragraph is not entirely within it's own block, create one and move
// the paragraph into it, and return that block.  Otherwise return 0.
HTMLElement* CompositeEditCommand::MoveParagraphContentsToNewBlockIfNecessary(
    const Position& pos,
    EditingState* editing_state) {}

void CompositeEditCommand::PushAnchorElementDown(Element* anchor_node,
                                                 EditingState* editing_state) {}

// Clone the paragraph between start and end under blockElement,
// preserving the hierarchy up to outerNode.

void CompositeEditCommand::CloneParagraphUnderNewElement(
    const Position& start,
    const Position& end,
    Node* passed_outer_node,
    Element* block_element,
    EditingState* editing_state) {}

// There are bugs in deletion when it removes a fully selected table/list.
// It expands and removes the entire table/list, but will let content
// before and after the table/list collapse onto one line.
// Deleting a paragraph will leave a placeholder. Remove it (and prune
// empty or unrendered parents).

void CompositeEditCommand::CleanupAfterDeletion(EditingState* editing_state) {}

void CompositeEditCommand::CleanupAfterDeletion(EditingState* editing_state,
                                                VisiblePosition destination) {}

// This is a version of moveParagraph that preserves style by keeping the
// original markup. It is currently used only by IndentOutdentCommand but it is
// meant to be used in the future by several other commands such as InsertList
// and the align commands.
// The blockElement parameter is the element to move the paragraph to, outerNode
// is the top element of the paragraph hierarchy.

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) {}

// FIXME: Send an appropriate shouldDeleteRange call.
bool CompositeEditCommand::BreakOutOfEmptyListItem(
    EditingState* editing_state) {}

// If the caret is in an empty quoted paragraph, and either there is nothing
// before that paragraph, or what is before is unquoted, and the user presses
// delete, unquote that paragraph.
bool CompositeEditCommand::BreakOutOfEmptyMailBlockquotedParagraph(
    EditingState* editing_state) {}

// Operations use this function to avoid inserting content into an anchor when
// at the start or the end of that anchor, as in NSTextView.
// FIXME: This is only an approximation of NSTextViews insertion behavior, which
// varies depending on how the caret was made.
Position CompositeEditCommand::PositionAvoidingSpecialElementBoundary(
    const Position& original,
    EditingState* editing_state) {}

// Splits the tree parent by parent until we reach the specified ancestor. We
// use VisiblePositions to determine if the split is necessary. Returns the last
// split node.
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) {}

// Determines whether a node is inside a range or visibly starts and ends at the
// boundaries of the range. Call this function to determine whether a node is
// visibly fit inside selectedRange
bool CompositeEditCommand::IsNodeVisiblyContainedWithin(
    Node& node,
    const EphemeralRange& selected_range) {}

void CompositeEditCommand::Trace(Visitor* visitor) const {}

void CompositeEditCommand::AppliedEditing() {}

}  // namespace blink