#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "base/trace_event/trace_event.h"
#include "third_party/blink/renderer/core/clipboard/clipboard_mime_types.h"
#include "third_party/blink/renderer/core/clipboard/data_object.h"
#include "third_party/blink/renderer/core/clipboard/data_transfer.h"
#include "third_party/blink/renderer/core/clipboard/data_transfer_access_policy.h"
#include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/range.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/editing/commands/editing_commands_utilities.h"
#include "third_party/blink/renderer/core/editing/editing_strategy.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/ime/edit_context.h"
#include "third_party/blink/renderer/core/editing/ime/input_method_controller.h"
#include "third_party/blink/renderer/core/editing/iterators/text_iterator.h"
#include "third_party/blink/renderer/core/editing/local_caret_rect.h"
#include "third_party/blink/renderer/core/editing/plain_text_range.h"
#include "third_party/blink/renderer/core/editing/position_iterator.h"
#include "third_party/blink/renderer/core/editing/position_with_affinity.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/serializers/html_interchange.h"
#include "third_party/blink/renderer/core/editing/state_machines/backspace_state_machine.h"
#include "third_party/blink/renderer/core/editing/state_machines/backward_grapheme_boundary_state_machine.h"
#include "third_party/blink/renderer/core/editing/state_machines/forward_grapheme_boundary_state_machine.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/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
#include "third_party/blink/renderer/core/html/forms/html_text_area_element.h"
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
#include "third_party/blink/renderer/core/html/html_body_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_dlist_element.h"
#include "third_party/blink/renderer/core/html/html_embed_element.h"
#include "third_party/blink/renderer/core/html/html_image_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_paragraph_element.h"
#include "third_party/blink/renderer/core/html/html_span_element.h"
#include "third_party/blink/renderer/core/html/html_table_cell_element.h"
#include "third_party/blink/renderer/core/html/html_table_element.h"
#include "third_party/blink/renderer/core/html/html_ulist_element.h"
#include "third_party/blink/renderer/core/html/image_document.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/html_element_factory.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_image.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/svg/svg_image_element.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/unicode.h"
namespace blink {
FormControlType;
namespace {
std::ostream& operator<<(std::ostream& os, PositionMoveType type) { … }
UChar WhitespaceRebalancingCharToAppend(const String& string,
bool start_is_start_of_paragraph,
bool should_emit_nbsp_before_end,
wtf_size_t index,
UChar previous) { … }
}
bool NeedsLayoutTreeUpdate(const Node& node) { … }
template <typename PositionType>
static bool NeedsLayoutTreeUpdateAlgorithm(const PositionType& position) { … }
bool NeedsLayoutTreeUpdate(const Position& position) { … }
bool NeedsLayoutTreeUpdate(const PositionInFlatTree& position) { … }
bool IsAtomicNode(const Node* node) { … }
bool IsAtomicNodeInFlatTree(const Node* node) { … }
bool IsNodeFullyContained(const EphemeralRange& range, const Node& node) { … }
bool IsUserSelectContain(const Node& node) { … }
enum EditableLevel { … };
static bool HasEditableLevel(const Node& node, EditableLevel editable_level) { … }
bool IsEditable(const Node& node) { … }
bool IsRichlyEditable(const Node& node) { … }
bool IsRootEditableElement(const Node& node) { … }
Element* RootEditableElement(const Node& node) { … }
ContainerNode* HighestEditableRoot(const Position& position) { … }
ContainerNode* HighestEditableRoot(const PositionInFlatTree& position) { … }
bool IsEditablePosition(const Position& position) { … }
bool IsEditablePosition(const PositionInFlatTree& p) { … }
bool IsRichlyEditablePosition(const Position& p) { … }
Element* RootEditableElementOf(const Position& p) { … }
Element* RootEditableElementOf(const PositionInFlatTree& p) { … }
template <typename Strategy>
PositionTemplate<Strategy> NextCandidateAlgorithm(
const PositionTemplate<Strategy>& position) { … }
Position NextCandidate(const Position& position) { … }
PositionInFlatTree NextCandidate(const PositionInFlatTree& position) { … }
template <typename Strategy>
static PositionTemplate<Strategy> NextVisuallyDistinctCandidateAlgorithm(
const PositionTemplate<Strategy>& position) { … }
Position NextVisuallyDistinctCandidate(const Position& position) { … }
PositionInFlatTree NextVisuallyDistinctCandidate(
const PositionInFlatTree& position) { … }
template <typename Strategy>
PositionTemplate<Strategy> PreviousCandidateAlgorithm(
const PositionTemplate<Strategy>& position) { … }
Position PreviousCandidate(const Position& position) { … }
PositionInFlatTree PreviousCandidate(const PositionInFlatTree& position) { … }
template <typename Strategy>
PositionTemplate<Strategy> PreviousVisuallyDistinctCandidateAlgorithm(
const PositionTemplate<Strategy>& position) { … }
Position PreviousVisuallyDistinctCandidate(const Position& position) { … }
PositionInFlatTree PreviousVisuallyDistinctCandidate(
const PositionInFlatTree& position) { … }
template <typename Strategy>
PositionTemplate<Strategy> FirstEditablePositionAfterPositionInRootAlgorithm(
const PositionTemplate<Strategy>& position,
const Node& highest_root) { … }
Position FirstEditablePositionAfterPositionInRoot(const Position& position,
const Node& highest_root) { … }
PositionInFlatTree FirstEditablePositionAfterPositionInRoot(
const PositionInFlatTree& position,
const Node& highest_root) { … }
template <typename Strategy>
PositionTemplate<Strategy> LastEditablePositionBeforePositionInRootAlgorithm(
const PositionTemplate<Strategy>& position,
const Node& highest_root) { … }
Position LastEditablePositionBeforePositionInRoot(const Position& position,
const Node& highest_root) { … }
PositionInFlatTree LastEditablePositionBeforePositionInRoot(
const PositionInFlatTree& position,
const Node& highest_root) { … }
template <typename StateMachine>
int FindNextBoundaryOffset(const String& str, int current) { … }
template int FindNextBoundaryOffset<BackwardGraphemeBoundaryStateMachine>(
const String& str,
int current);
template int FindNextBoundaryOffset<ForwardGraphemeBoundaryStateMachine>(
const String& str,
int current);
int PreviousGraphemeBoundaryOf(const Node& node, int current) { … }
static int PreviousBackwardDeletionOffsetOf(const Node& node, int current) { … }
int NextGraphemeBoundaryOf(const Node& node, int current) { … }
template <typename Strategy>
PositionTemplate<Strategy> PreviousPositionOfAlgorithm(
const PositionTemplate<Strategy>& position,
PositionMoveType move_type) { … }
Position PreviousPositionOf(const Position& position,
PositionMoveType move_type) { … }
PositionInFlatTree PreviousPositionOf(const PositionInFlatTree& position,
PositionMoveType move_type) { … }
template <typename Strategy>
PositionTemplate<Strategy> NextPositionOfAlgorithm(
const PositionTemplate<Strategy>& position,
PositionMoveType move_type) { … }
Position NextPositionOf(const Position& position, PositionMoveType move_type) { … }
PositionInFlatTree NextPositionOf(const PositionInFlatTree& position,
PositionMoveType move_type) { … }
bool IsEnclosingBlock(const Node* node) { … }
Element* EnclosingBlock(const Node* node, EditingBoundaryCrossingRule rule) { … }
template <typename Strategy>
Element* EnclosingBlockAlgorithm(const PositionTemplate<Strategy>& position,
EditingBoundaryCrossingRule rule) { … }
Element* EnclosingBlock(const Position& position,
EditingBoundaryCrossingRule rule) { … }
Element* EnclosingBlock(const PositionInFlatTree& position,
EditingBoundaryCrossingRule rule) { … }
Element* EnclosingBlockFlowElement(const Node& node) { … }
template <typename Strategy>
TextDirection DirectionOfEnclosingBlockOfAlgorithm(
const PositionTemplate<Strategy>& position) { … }
TextDirection DirectionOfEnclosingBlockOf(const Position& position) { … }
TextDirection DirectionOfEnclosingBlockOf(const PositionInFlatTree& position) { … }
TextDirection PrimaryDirectionOf(const Node& node) { … }
String StringWithRebalancedWhitespace(const String& string,
bool start_is_start_of_paragraph,
bool should_emit_nbs_pbefore_end) { … }
String RepeatString(const String& string, unsigned count) { … }
template <typename Strategy>
static Element* TableElementJustBeforeAlgorithm(
const VisiblePositionTemplate<Strategy>& visible_position) { … }
Element* TableElementJustBefore(const VisiblePosition& visible_position) { … }
Element* TableElementJustBefore(
const VisiblePositionInFlatTree& visible_position) { … }
Element* EnclosingTableCell(const Position& p) { … }
Element* EnclosingTableCell(const PositionInFlatTree& p) { … }
Element* TableElementJustAfter(const VisiblePosition& visible_position) { … }
Position PositionBeforeNode(const Node& node) { … }
Position PositionAfterNode(const Node& node) { … }
bool IsHTMLListElement(const Node* n) { … }
bool IsListItem(const Node* n) { … }
bool IsListItemTag(const Node* n) { … }
bool IsListElementTag(const Node* n) { … }
bool IsPresentationalHTMLElement(const Node* node) { … }
Element* AssociatedElementOf(const Position& position) { … }
Element* EnclosingElementWithTag(const Position& p,
const QualifiedName& tag_name) { … }
template <typename Strategy>
static Node* EnclosingNodeOfTypeAlgorithm(const PositionTemplate<Strategy>& p,
bool (*node_is_of_type)(const Node*),
EditingBoundaryCrossingRule rule) { … }
Node* EnclosingNodeOfType(const Position& p,
bool (*node_is_of_type)(const Node*),
EditingBoundaryCrossingRule rule) { … }
Node* EnclosingNodeOfType(const PositionInFlatTree& p,
bool (*node_is_of_type)(const Node*),
EditingBoundaryCrossingRule rule) { … }
Node* HighestEnclosingNodeOfType(const Position& p,
bool (*node_is_of_type)(const Node*),
EditingBoundaryCrossingRule rule,
Node* stay_within) { … }
Element* EnclosingAnchorElement(const Position& p) { … }
bool IsDisplayInsideTable(const Node* node) { … }
bool IsTableCell(const Node* node) { … }
HTMLElement* CreateDefaultParagraphElement(Document& document) { … }
bool IsTabHTMLSpanElement(const Node* node) { … }
bool IsTabHTMLSpanElementTextNode(const Node* node) { … }
HTMLSpanElement* TabSpanElement(const Node* node) { … }
static HTMLSpanElement* CreateTabSpanElement(Document& document,
Text* tab_text_node) { … }
HTMLSpanElement* CreateTabSpanElement(Document& document,
const String& tab_text) { … }
HTMLSpanElement* CreateTabSpanElement(Document& document) { … }
static bool IsInPlaceholder(const TextControlElement& text_control,
const Position& position) { … }
static Element* UserSelectContainBoundaryOf(const Position& position) { … }
PositionWithAffinity PositionRespectingEditingBoundary(
const Position& position,
const HitTestResult& hit_test_result) { … }
PositionWithAffinity AdjustForEditingBoundary(
const PositionWithAffinity& position_with_affinity) { … }
PositionWithAffinity AdjustForEditingBoundary(const Position& position) { … }
Position ComputePlaceholderToCollapseAt(const Position& insertion_pos) { … }
Position ComputePositionForNodeRemoval(const Position& position,
const Node& node) { … }
bool IsMailHTMLBlockquoteElement(const Node* node) { … }
bool ElementCannotHaveEndTag(const Node& node) { … }
int IndexForVisiblePosition(const VisiblePosition& visible_position,
ContainerNode*& scope) { … }
EphemeralRange MakeRange(const VisiblePosition& start,
const VisiblePosition& end) { … }
template <typename Strategy>
static EphemeralRangeTemplate<Strategy> NormalizeRangeAlgorithm(
const EphemeralRangeTemplate<Strategy>& range) { … }
EphemeralRange NormalizeRange(const EphemeralRange& range) { … }
EphemeralRangeInFlatTree NormalizeRange(const EphemeralRangeInFlatTree& range) { … }
VisiblePosition VisiblePositionForIndex(int index, ContainerNode* scope) { … }
template <typename Strategy>
bool AreSameRangesAlgorithm(Node* node,
const PositionTemplate<Strategy>& start_position,
const PositionTemplate<Strategy>& end_position) { … }
bool AreSameRanges(Node* node,
const Position& start_position,
const Position& end_position) { … }
bool AreSameRanges(Node* node,
const PositionInFlatTree& start_position,
const PositionInFlatTree& end_position) { … }
bool IsRenderedAsNonInlineTableImageOrHR(const Node* node) { … }
bool IsNonTableCellHTMLBlockElement(const Node* node) { … }
bool IsBlockFlowElement(const Node& node) { … }
bool IsInPasswordField(const Position& position) { … }
wtf_size_t ComputeDistanceToLeftGraphemeBoundary(const Position& position) { … }
wtf_size_t ComputeDistanceToRightGraphemeBoundary(const Position& position) { … }
gfx::QuadF LocalToAbsoluteQuadOf(const LocalCaretRect& caret_rect) { … }
const StaticRangeVector* TargetRangesForInputEvent(const Node& node) { … }
DispatchEventResult DispatchBeforeInputInsertText(
Node* target,
const String& data,
InputEvent::InputType input_type,
const StaticRangeVector* ranges) { … }
DispatchEventResult DispatchBeforeInputEditorCommand(
Node* target,
InputEvent::InputType input_type,
const StaticRangeVector* ranges) { … }
DispatchEventResult DispatchBeforeInputDataTransfer(
Node* target,
InputEvent::InputType input_type,
DataTransfer* data_transfer) { … }
void InsertTextAndSendInputEventsOfTypeInsertReplacementText(
LocalFrame& frame,
const String& replacement,
bool allow_edit_context) { … }
static bool IsEmptyNonEditableNodeInEditable(const Node& node) { … }
bool EditingIgnoresContent(const Node& node) { … }
ContainerNode* RootEditableElementOrTreeScopeRootNodeOf(
const Position& position) { … }
static scoped_refptr<Image> ImageFromNode(const Node& node) { … }
AtomicString GetUrlStringFromNode(const Node& node) { … }
void WriteImageToClipboard(SystemClipboard& system_clipboard,
const scoped_refptr<Image>& image,
const KURL& url_string,
const String& title) { … }
void WriteImageNodeToClipboard(SystemClipboard& system_clipboard,
const Node& node,
const String& title) { … }
Element* FindEventTargetFrom(LocalFrame& frame,
const VisibleSelection& selection) { … }
HTMLImageElement* ImageElementFromImageDocument(const Document* document) { … }
}