/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
 * reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "core/dom/Text.h"

#include "bindings/core/v8/ExceptionState.h"
#include "core/SVGNames.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/FirstLetterPseudoElement.h"
#include "core/dom/LayoutTreeBuilder.h"
#include "core/dom/LayoutTreeBuilderTraversal.h"
#include "core/dom/NodeComputedStyle.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/ScopedEventQueue.h"
#include "core/layout/LayoutText.h"
#include "core/layout/LayoutTextCombine.h"
#include "core/layout/LayoutTextFragment.h"
#include "core/layout/api/LayoutTextItem.h"
#include "core/layout/svg/LayoutSVGInlineText.h"
#include "core/svg/SVGForeignObjectElement.h"
#include "platform/bindings/DOMDataStore.h"
#include "platform/wtf/text/CString.h"
#include "platform/wtf/text/StringBuilder.h"

namespace blink {

Text* Text::Create(Document& document, const String& data) {
  return new Text(document, data, kCreateText);
}

Text* Text::CreateEditingText(Document& document, const String& data) {
  return new Text(document, data, kCreateEditingText);
}

Node* Text::MergeNextSiblingNodesIfPossible() {
  // Remove empty text nodes.
  if (!length()) {
    // Care must be taken to get the next node before removing the current node.
    Node* next_node = NodeTraversal::NextPostOrder(*this);
    remove(IGNORE_EXCEPTION_FOR_TESTING);
    return next_node;
  }

  // Merge text nodes.
  while (Node* next_sibling = this->nextSibling()) {
    if (next_sibling->getNodeType() != kTextNode)
      break;

    Text* next_text = ToText(next_sibling);

    // Remove empty text nodes.
    if (!next_text->length()) {
      next_text->remove(IGNORE_EXCEPTION_FOR_TESTING);
      continue;
    }

    // Both non-empty text nodes. Merge them.
    unsigned offset = length();
    String next_text_data = next_text->data();
    String old_text_data = data();
    SetDataWithoutUpdate(data() + next_text_data);
    UpdateTextLayoutObject(old_text_data.length(), 0);

    GetDocument().DidMergeTextNodes(*this, *next_text, offset);

    // Empty nextText for layout update.
    next_text->SetDataWithoutUpdate(g_empty_string);
    next_text->UpdateTextLayoutObject(0, next_text_data.length());

    // Restore nextText for mutation event.
    next_text->SetDataWithoutUpdate(next_text_data);
    next_text->UpdateTextLayoutObject(0, 0);

    GetDocument().IncDOMTreeVersion();
    DidModifyData(old_text_data, CharacterData::kUpdateFromNonParser);
    next_text->remove(IGNORE_EXCEPTION_FOR_TESTING);
  }

  return NodeTraversal::NextPostOrder(*this);
}

Text* Text::splitText(unsigned offset, ExceptionState& exception_state) {
  // IndexSizeError: Raised if the specified offset is negative or greater than
  // the number of 16-bit units in data.
  if (offset > length()) {
    exception_state.ThrowDOMException(
        kIndexSizeError, "The offset " + String::Number(offset) +
                             " is larger than the Text node's length.");
    return nullptr;
  }

  EventQueueScope scope;
  String old_str = data();
  Text* new_text = CloneWithData(old_str.Substring(offset));
  SetDataWithoutUpdate(old_str.Substring(0, offset));

  DidModifyData(old_str, CharacterData::kUpdateFromNonParser);

  if (parentNode())
    parentNode()->InsertBefore(new_text, nextSibling(), exception_state);
  if (exception_state.HadException())
    return nullptr;

  if (GetLayoutObject())
    GetLayoutObject()->SetTextWithOffset(DataImpl(), 0, old_str.length());

  if (parentNode())
    GetDocument().DidSplitTextNode(*this);
  else
    GetDocument().DidRemoveText(*this, offset, old_str.length() - offset);

  // [NewObject] must always create a new wrapper.  Check that a wrapper
  // does not exist yet.
  DCHECK(
      DOMDataStore::GetWrapper(new_text, v8::Isolate::GetCurrent()).IsEmpty());

  return new_text;
}

static const Text* EarliestLogicallyAdjacentTextNode(const Text* t) {
  for (const Node* n = t->previousSibling(); n; n = n->previousSibling()) {
    Node::NodeType type = n->getNodeType();
    if (type == Node::kTextNode || type == Node::kCdataSectionNode) {
      t = ToText(n);
      continue;
    }

    break;
  }
  return t;
}

static const Text* LatestLogicallyAdjacentTextNode(const Text* t) {
  for (const Node* n = t->nextSibling(); n; n = n->nextSibling()) {
    Node::NodeType type = n->getNodeType();
    if (type == Node::kTextNode || type == Node::kCdataSectionNode) {
      t = ToText(n);
      continue;
    }

    break;
  }
  return t;
}

String Text::wholeText() const {
  const Text* start_text = EarliestLogicallyAdjacentTextNode(this);
  const Text* end_text = LatestLogicallyAdjacentTextNode(this);

  Node* one_past_end_text = end_text->nextSibling();
  unsigned result_length = 0;
  for (const Node* n = start_text; n != one_past_end_text;
       n = n->nextSibling()) {
    if (!n->IsTextNode())
      continue;
    const String& data = ToText(n)->data();
    if (std::numeric_limits<unsigned>::max() - data.length() < result_length)
      CRASH();
    result_length += data.length();
  }
  StringBuilder result;
  result.ReserveCapacity(result_length);
  for (const Node* n = start_text; n != one_past_end_text;
       n = n->nextSibling()) {
    if (!n->IsTextNode())
      continue;
    result.Append(ToText(n)->data());
  }
  DCHECK_EQ(result.length(), result_length);

  return result.ToString();
}

Text* Text::ReplaceWholeText(const String& new_text) {
  // Remove all adjacent text nodes, and replace the contents of this one.

  // Protect startText and endText against mutation event handlers removing the
  // last ref
  Text* start_text = const_cast<Text*>(EarliestLogicallyAdjacentTextNode(this));
  Text* end_text = const_cast<Text*>(LatestLogicallyAdjacentTextNode(this));

  ContainerNode* parent = parentNode();  // Protect against mutation handlers
                                         // moving this node during traversal
  for (Node* n = start_text;
       n && n != this && n->IsTextNode() && n->parentNode() == parent;) {
    Node* node_to_remove = n;
    n = node_to_remove->nextSibling();
    parent->RemoveChild(node_to_remove, IGNORE_EXCEPTION_FOR_TESTING);
  }

  if (this != end_text) {
    Node* one_past_end_text = end_text->nextSibling();
    for (Node* n = nextSibling(); n && n != one_past_end_text &&
                                  n->IsTextNode() &&
                                  n->parentNode() == parent;) {
      Node* node_to_remove = n;
      n = node_to_remove->nextSibling();
      parent->RemoveChild(node_to_remove, IGNORE_EXCEPTION_FOR_TESTING);
    }
  }

  if (new_text.IsEmpty()) {
    if (parent && parentNode() == parent)
      parent->RemoveChild(this, IGNORE_EXCEPTION_FOR_TESTING);
    return nullptr;
  }

  setData(new_text);
  return this;
}

String Text::nodeName() const {
  return "#text";
}

Node::NodeType Text::getNodeType() const {
  return kTextNode;
}

Node* Text::cloneNode(bool /*deep*/, ExceptionState&) {
  return CloneWithData(data());
}

static inline bool CanHaveWhitespaceChildren(const LayoutObject& parent) {
  // <button> and <fieldset> should allow whitespace even though
  // LayoutFlexibleBox doesn't.
  if (parent.IsLayoutButton() || parent.IsFieldset())
    return true;

  if (parent.IsTable() || parent.IsTableRow() || parent.IsTableSection() ||
      parent.IsLayoutTableCol() || parent.IsFrameSet() ||
      parent.IsFlexibleBox() || parent.IsLayoutGrid() || parent.IsSVGRoot() ||
      parent.IsSVGContainer() || parent.IsSVGImage() || parent.IsSVGShape()) {
    return false;
  }
  return true;
}

bool Text::TextLayoutObjectIsNeeded(const ComputedStyle& style,
                                    const LayoutObject& parent) const {
  DCHECK(!GetDocument().ChildNeedsDistributionRecalc());

  if (!parent.CanHaveChildren())
    return false;

  if (IsEditingText())
    return true;

  if (!length())
    return false;

  if (style.Display() == EDisplay::kNone)
    return false;

  if (!ContainsOnlyWhitespace())
    return true;

  if (!CanHaveWhitespaceChildren(parent))
    return false;

  // pre-wrap in SVG never makes layoutObject.
  if (style.WhiteSpace() == EWhiteSpace::kPreWrap && parent.IsSVG())
    return false;

  // pre/pre-wrap/pre-line always make layoutObjects.
  if (style.PreserveNewline())
    return true;

  // Avoiding creation of a layoutObject for the text node is a non-essential
  // memory optimization.  So to avoid blowing up on very wide DOMs, we limit
  // the number of siblings to visit.
  unsigned max_siblings_to_visit = 50;

  const LayoutObject* prev =
      LayoutTreeBuilderTraversal::PreviousSiblingLayoutObject(
          *this, max_siblings_to_visit);
  if (prev && prev->IsBR())  // <span><br/> <br/></span>
    return false;

  if (parent.IsLayoutInline()) {
    // <span><div/> <div/></span>
    if (prev && !prev->IsInline() && !prev->IsFloatingOrOutOfFlowPositioned())
      return false;
  } else {
    if (parent.IsLayoutBlock() && !parent.ChildrenInline() &&
        (!prev || !prev->IsInline()))
      return false;

    LayoutObject* first = parent.SlowFirstChild();
    for (; first && first->IsFloatingOrOutOfFlowPositioned() &&
           max_siblings_to_visit;
         first = first->NextSibling(), --max_siblings_to_visit) {
    }
    if (!first || first == GetLayoutObject() ||
        LayoutTreeBuilderTraversal::NextSiblingLayoutObject(
            *this, max_siblings_to_visit) == first) {
      // If we're adding children to this flow our previous siblings are not in
      // the layout tree yet so we cannot know if we will be the first child in
      // the line and collapse away. We have to assume we need a layout object.
      Node* first_child_node =
          parent.GetNode()
              ? LayoutTreeBuilderTraversal::FirstChild(*parent.GetNode())
              : nullptr;
      if (first && first == GetLayoutObject() && first_child_node &&
          !first_child_node->GetLayoutObject())
        return true;

      // Whitespace at the start of a block just goes away.  Don't even
      // make a layout object for this text.
      return !first_child_node;
    }
  }
  return true;
}

static bool IsSVGText(Text* text) {
  Node* parent_or_shadow_host_node = text->ParentOrShadowHostNode();
  DCHECK(parent_or_shadow_host_node);
  return parent_or_shadow_host_node->IsSVGElement() &&
         !isSVGForeignObjectElement(*parent_or_shadow_host_node);
}

LayoutText* Text::CreateTextLayoutObject(const ComputedStyle& style) {
  if (IsSVGText(this))
    return new LayoutSVGInlineText(this, DataImpl());

  if (style.HasTextCombine())
    return new LayoutTextCombine(this, DataImpl());

  return new LayoutText(this, DataImpl());
}

void Text::AttachLayoutTree(const AttachContext& context) {
  ContainerNode* style_parent = LayoutTreeBuilderTraversal::Parent(*this);
  LayoutObject* parent_layout_object =
      LayoutTreeBuilderTraversal::ParentLayoutObject(*this);

  if (style_parent && parent_layout_object) {
    DCHECK(style_parent->GetComputedStyle());
    if (TextLayoutObjectIsNeeded(*style_parent->GetComputedStyle(),
                                 *parent_layout_object)) {
      LayoutTreeBuilderForText(*this, parent_layout_object,
                               style_parent->MutableComputedStyle())
          .CreateLayoutObject();
    }
  }
  CharacterData::AttachLayoutTree(context);
}

void Text::ReattachLayoutTreeIfNeeded() {
  bool layout_object_is_needed = false;
  ContainerNode* style_parent = LayoutTreeBuilderTraversal::Parent(*this);
  LayoutObject* parent_layout_object =
      LayoutTreeBuilderTraversal::ParentLayoutObject(*this);
  if (style_parent && parent_layout_object) {
    DCHECK(style_parent->GetComputedStyle());
    layout_object_is_needed = TextLayoutObjectIsNeeded(
        *style_parent->GetComputedStyle(), *parent_layout_object);
  }

  if (layout_object_is_needed == !!GetLayoutObject())
    return;

  // The following is almost the same as Node::reattachLayoutTree() except that
  // we create a layoutObject only if needed.  Not calling reattachLayoutTree()
  // to avoid repeated calls to Text::textLayoutObjectIsNeeded().
  AttachContext reattach_context;
  reattach_context.performing_reattach = true;

  if (GetStyleChangeType() < kNeedsReattachStyleChange)
    DetachLayoutTree(reattach_context);
  if (layout_object_is_needed) {
    LayoutTreeBuilderForText(*this, parent_layout_object,
                             style_parent->MutableComputedStyle())
        .CreateLayoutObject();
  }
  CharacterData::AttachLayoutTree(reattach_context);
}

void Text::RecalcTextStyle(StyleRecalcChange change) {
  if (LayoutTextItem layout_item = LayoutTextItem(this->GetLayoutObject())) {
    if (change != kNoChange || NeedsStyleRecalc())
      layout_item.SetStyle(
          GetDocument().EnsureStyleResolver().StyleForText(this));
    if (NeedsStyleRecalc())
      layout_item.SetText(DataImpl());
    ClearNeedsStyleRecalc();
  } else if (NeedsStyleRecalc() || NeedsWhitespaceLayoutObject()) {
    SetNeedsReattachLayoutTree();
  }
}

void Text::RebuildTextLayoutTree(Text* next_text_sibling) {
  DCHECK(!ChildNeedsStyleRecalc());
  DCHECK(NeedsReattachLayoutTree());
  DCHECK(parentNode());

  ReattachLayoutTree();
  if (GetLayoutObject())
    ReattachWhitespaceSiblingsIfNeeded(next_text_sibling);
  ClearNeedsReattachLayoutTree();
}

// If a whitespace node had no layoutObject and goes through a recalcStyle it
// may need to create one if the parent style now has white-space: pre.
bool Text::NeedsWhitespaceLayoutObject() {
  DCHECK(!GetLayoutObject());
  if (const ComputedStyle* style = ParentComputedStyle())
    return style->PreserveNewline();
  return false;
}

// Passing both |textNode| and its layout object because repeated calls to
// |Node::layoutObject()| are discouraged.
static bool ShouldUpdateLayoutByReattaching(const Text& text_node,
                                            LayoutText* text_layout_object) {
  DCHECK_EQ(text_node.GetLayoutObject(), text_layout_object);
  if (!text_layout_object)
    return true;
  // In general we do not want to branch on lifecycle states such as
  // |childNeedsDistributionRecalc|, but this code tries to figure out if we can
  // use an optimized code path that avoids reattach.
  if (!text_node.GetDocument().ChildNeedsDistributionRecalc() &&
      !text_node.TextLayoutObjectIsNeeded(*text_layout_object->Style(),
                                          *text_layout_object->Parent())) {
    return true;
  }
  if (text_layout_object->IsTextFragment()) {
    // Changes of |textNode| may change first letter part, so we should
    // reattach.
    return ToLayoutTextFragment(text_layout_object)
        ->GetFirstLetterPseudoElement();
  }
  return false;
}

void Text::UpdateTextLayoutObject(unsigned offset_of_replaced_data,
                                  unsigned length_of_replaced_data) {
  if (!InActiveDocument())
    return;
  LayoutText* text_layout_object = GetLayoutObject();
  if (ShouldUpdateLayoutByReattaching(*this, text_layout_object)) {
    LazyReattachIfAttached();
    return;
  }

  text_layout_object->SetTextWithOffset(DataImpl(), offset_of_replaced_data,
                                        length_of_replaced_data);
}

Text* Text::CloneWithData(const String& data) {
  return Create(GetDocument(), data);
}

DEFINE_TRACE(Text) {
  CharacterData::Trace(visitor);
}

}  // namespace blink
