/*
 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
 *                     1999 Lars Knoll <knoll@kde.org>
 *                     1999 Antti Koivisto <koivisto@kde.org>
 *                     2000 Simon Hausmann <hausmann@kde.org>
 *                     2000 Stefan Schimanski <1Stein@gmx.de>
 *                     2001 George Staikos <staikos@kde.org>
 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All
 * rights reserved.
 * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
 * Copyright (C) 2008 Google Inc.
 *
 * 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 "third_party/blink/renderer/core/frame/frame.h"

#include <memory>

#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_remote_frame_client.h"
#include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/dom/document_type.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/increment_load_event_delay_count.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/execution_context/window_agent_factory.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/page_dismissal_scope.h"
#include "third_party/blink/renderer/core/frame/remote_frame_owner.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/web_remote_frame_impl.h"
#include "third_party/blink/renderer/core/html/html_frame_element_base.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/loader/form_submission.h"
#include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/instrumentation/instance_counters.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"

namespace blink {

// static
Frame* Frame::ResolveFrame(const FrameToken& frame_token) {
  if (frame_token.Is<RemoteFrameToken>())
    return RemoteFrame::FromFrameToken(frame_token.GetAs<RemoteFrameToken>());
  DCHECK(frame_token.Is<LocalFrameToken>());
  return LocalFrame::FromFrameToken(frame_token.GetAs<LocalFrameToken>());
}

Frame::~Frame() {
  InstanceCounters::DecrementCounter(InstanceCounters::kFrameCounter);
  DCHECK(!owner_);
  DCHECK(IsDetached());
}

void Frame::Trace(Visitor* visitor) const {
  visitor->Trace(tree_node_);
  visitor->Trace(page_);
  visitor->Trace(owner_);
  visitor->Trace(window_proxy_manager_);
  visitor->Trace(dom_window_);
  visitor->Trace(client_);
  visitor->Trace(opener_);
  visitor->Trace(parent_);
  visitor->Trace(previous_sibling_);
  visitor->Trace(next_sibling_);
  visitor->Trace(first_child_);
  visitor->Trace(last_child_);
  visitor->Trace(provisional_frame_);
  visitor->Trace(navigation_rate_limiter_);
  visitor->Trace(window_agent_factory_);
  visitor->Trace(opened_frame_tracker_);
}

bool Frame::Detach(FrameDetachType type) {
  DCHECK(client_);
  // Detach() can be re-entered, so this can't simply DCHECK(IsAttached()).
  DCHECK(!IsDetached());
  lifecycle_.AdvanceTo(FrameLifecycle::kDetaching);
  PageDismissalScope in_page_dismissal;

  if (!DetachImpl(type))
    return false;

  DCHECK(!IsDetached());
  DCHECK(client_);

  GetPage()->GetFocusController().FrameDetached(this);
  // FrameDetached() can fire JS event listeners, so `this` might have been
  // reentrantly detached.
  if (!client_)
    return false;

  DCHECK(!IsDetached());

  // TODO(dcheng): FocusController::FrameDetached() *should* fire JS events,
  // hence the above check for `client_` being null. However, when this was
  // previously placed before the `FrameDetached()` call, nothing crashes, which
  // is suspicious. Investigate if we really don't need to fire JS events--and
  // if we don't, move `forbid_scripts` up to be instantiated sooner and
  // simplify this code.
  ScriptForbiddenScope forbid_scripts;

  if (type == FrameDetachType::kRemove) {
    if (provisional_frame_) {
      provisional_frame_->Detach(FrameDetachType::kRemove);
    }
    SetOpener(nullptr);
    // Clearing the window proxies can call back into `LocalFrameClient`, so
    // this must be done before nulling out `client_` below.
    GetWindowProxyManager()->ClearForClose();
  } else {
    // In the case of a swap, detach is carefully coordinated with `Swap()`.
    // Intentionally avoid clearing the opener with `SetOpener(nullptr)` here,
    // since `Swap()` needs the original value to clone to the new frame.
    DCHECK_EQ(FrameDetachType::kSwap, type);

    // Clearing the window proxies can call back into `LocalFrameClient`, so
    // this must be done before nulling out `client_` below.
    // `ClearForSwap()` preserves the v8::Objects that represent the global
    // proxies; `Swap()` will later use `ReleaseGlobalProxies()` +
    // `SetGlobalProxies()` to adopt the global proxies into the new frame.
    GetWindowProxyManager()->ClearForSwap();
  }

  // After this, we must no longer talk to the client since this clears
  // its owning reference back to our owning LocalFrame.
  client_->Detached(type);
  client_ = nullptr;
  // Mark the frame as detached once |client_| is null, as most of the frame has
  // been torn down at this point.
  // TODO(dcheng): Once https://crbug.com/820782 is fixed, Frame::Client() will
  // also assert that it is only accessed when the frame is not detached.
  lifecycle_.AdvanceTo(FrameLifecycle::kDetached);
  // TODO(dcheng): This currently needs to happen after calling
  // FrameClient::Detached() to make it easier for FrameClient::Detached()
  // implementations to detect provisional frames and avoid removing them from
  // the frame tree. https://crbug.com/578349.
  DisconnectOwnerElement();
  page_ = nullptr;
  embedding_token_ = base::nullopt;

  return true;
}

void Frame::DisconnectOwnerElement() {
  if (!owner_)
    return;

  // TODO(https://crbug.com/578349): If this is a provisional frame, the frame
  // owner doesn't actually point to this frame, so don't clear it. Note that
  // this can't use IsProvisional() because the |client_| is null already.
  if (owner_->ContentFrame() == this)
    owner_->ClearContentFrame();

  owner_ = nullptr;
}

Page* Frame::GetPage() const {
  return page_;
}

bool Frame::IsMainFrame() const {
  return !Tree().Parent();
}

bool Frame::IsCrossOriginToMainFrame() const {
  DCHECK(GetSecurityContext());
  const SecurityOrigin* security_origin =
      GetSecurityContext()->GetSecurityOrigin();
  return !security_origin->CanAccess(
      Tree().Top().GetSecurityContext()->GetSecurityOrigin());
}

bool Frame::IsCrossOriginToParentFrame() const {
  DCHECK(GetSecurityContext());
  if (IsMainFrame())
    return false;
  Frame* parent = Tree().Parent();
  const SecurityOrigin* parent_security_origin =
      parent->GetSecurityContext()->GetSecurityOrigin();
  const SecurityOrigin* security_origin =
      GetSecurityContext()->GetSecurityOrigin();
  return !security_origin->CanAccess(parent_security_origin);
}

HTMLFrameOwnerElement* Frame::DeprecatedLocalOwner() const {
  return DynamicTo<HTMLFrameOwnerElement>(owner_.Get());
}

static ChromeClient& GetEmptyChromeClient() {
  DEFINE_STATIC_LOCAL(Persistent<EmptyChromeClient>, client,
                      (MakeGarbageCollected<EmptyChromeClient>()));
  return *client;
}

ChromeClient& Frame::GetChromeClient() const {
  if (Page* page = this->GetPage())
    return page->GetChromeClient();
  return GetEmptyChromeClient();
}

Frame* Frame::FindUnsafeParentScrollPropagationBoundary() {
  Frame* current_frame = this;
  Frame* ancestor_frame = Tree().Parent();

  while (ancestor_frame) {
    if (!ancestor_frame->GetSecurityContext()->GetSecurityOrigin()->CanAccess(
            GetSecurityContext()->GetSecurityOrigin()))
      return current_frame;
    current_frame = ancestor_frame;
    ancestor_frame = ancestor_frame->Tree().Parent();
  }
  return nullptr;
}

LayoutEmbeddedContent* Frame::OwnerLayoutObject() const {
  if (!DeprecatedLocalOwner())
    return nullptr;
  return DeprecatedLocalOwner()->GetLayoutEmbeddedContent();
}

Settings* Frame::GetSettings() const {
  if (GetPage())
    return &GetPage()->GetSettings();
  return nullptr;
}

WindowProxy* Frame::GetWindowProxy(DOMWrapperWorld& world) {
  return window_proxy_manager_->GetWindowProxy(world);
}

void Frame::DidChangeVisibilityState() {
  HeapVector<Member<Frame>> child_frames;
  for (Frame* child = Tree().FirstChild(); child;
       child = child->Tree().NextSibling())
    child_frames.push_back(child);
  for (wtf_size_t i = 0; i < child_frames.size(); ++i)
    child_frames[i]->DidChangeVisibilityState();
}

void Frame::NotifyUserActivationInFrameTree(
    mojom::blink::UserActivationNotificationType notification_type) {
  for (Frame* node = this; node; node = node->Tree().Parent()) {
    node->user_activation_state_.Activate(notification_type);
  }

  // See the "Same-origin Visibility" section in |UserActivationState| class
  // doc.
  auto* local_frame = DynamicTo<LocalFrame>(this);
  if (local_frame &&
      RuntimeEnabledFeatures::UserActivationSameOriginVisibilityEnabled()) {
    const SecurityOrigin* security_origin =
        local_frame->GetSecurityContext()->GetSecurityOrigin();

    Frame& root = Tree().Top();
    for (Frame* node = &root; node; node = node->Tree().TraverseNext(&root)) {
      auto* local_frame_node = DynamicTo<LocalFrame>(node);
      if (local_frame_node &&
          security_origin->CanAccess(
              local_frame_node->GetSecurityContext()->GetSecurityOrigin())) {
        node->user_activation_state_.Activate(notification_type);
      }
    }
  }
}

bool Frame::ConsumeTransientUserActivationInFrameTree() {
  bool was_active = user_activation_state_.IsActive();
  Frame& root = Tree().Top();

  // To record UMA once per consumption, we arbitrarily picked the LocalFrame
  // for root.
  if (IsA<LocalFrame>(root))
    root.user_activation_state_.RecordPreconsumptionUma();

  for (Frame* node = &root; node; node = node->Tree().TraverseNext(&root))
    node->user_activation_state_.ConsumeIfActive();

  return was_active;
}

void Frame::ClearUserActivationInFrameTree() {
  for (Frame* node = this; node; node = node->Tree().TraverseNext(this))
    node->user_activation_state_.Clear();
}

void Frame::SetOwner(FrameOwner* owner) {
  owner_ = owner;
  UpdateInertIfPossible();
  UpdateInheritedEffectiveTouchActionIfPossible();
}

bool Frame::IsAdSubframe() const {
  return ad_frame_type_ != mojom::blink::AdFrameType::kNonAd;
}

bool Frame::IsAdRoot() const {
  return ad_frame_type_ == mojom::blink::AdFrameType::kRootAd;
}

void Frame::UpdateInertIfPossible() {
  if (auto* frame_owner_element =
          DynamicTo<HTMLFrameOwnerElement>(owner_.Get())) {
    if (frame_owner_element->IsInert())
      SetIsInert(true);
  }
}

void Frame::UpdateInheritedEffectiveTouchActionIfPossible() {
  if (owner_) {
    Frame* owner_frame = owner_->ContentFrame();
    if (owner_frame) {
      SetInheritedEffectiveTouchAction(
          owner_frame->InheritedEffectiveTouchAction());
    }
  }
}

void Frame::UpdateVisibleToHitTesting() {
  bool parent_visible_to_hit_testing = true;
  if (auto* parent = Tree().Parent())
    parent_visible_to_hit_testing = parent->GetVisibleToHitTesting();

  bool self_visible_to_hit_testing = true;
  if (auto* local_owner = DynamicTo<HTMLFrameOwnerElement>(owner_.Get())) {
    self_visible_to_hit_testing =
        local_owner->GetLayoutObject()
            ? local_owner->GetLayoutObject()->Style()->VisibleToHitTesting()
            : true;
  }

  bool visible_to_hit_testing =
      parent_visible_to_hit_testing && self_visible_to_hit_testing;
  bool changed = visible_to_hit_testing_ != visible_to_hit_testing;
  visible_to_hit_testing_ = visible_to_hit_testing;
  if (changed)
    DidChangeVisibleToHitTesting();
}

const std::string& Frame::ToTraceValue() {
  // token's ToString() is latin1.
  if (!trace_value_)
    trace_value_ = devtools_frame_token_.ToString();
  return trace_value_.value();
}

void Frame::SetEmbeddingToken(const base::UnguessableToken& embedding_token) {
  embedding_token_ = embedding_token;
  if (auto* owner = DynamicTo<HTMLFrameOwnerElement>(Owner())) {
    // The embedding token is also used as the AXTreeID to reference the child
    // accessibility tree for an HTMLFrameOwnerElement, so we need to notify the
    // AXObjectCache object whenever this changes, to get the AX tree updated.
    if (AXObjectCache* cache = owner->GetDocument().ExistingAXObjectCache())
      cache->EmbeddingTokenChanged(owner);
  }
}

Frame::Frame(FrameClient* client,
             Page& page,
             FrameOwner* owner,
             Frame* parent,
             Frame* previous_sibling,
             FrameInsertType insert_type,
             const FrameToken& frame_token,
             WindowProxyManager* window_proxy_manager,
             WindowAgentFactory* inheriting_agent_factory)
    : tree_node_(this),
      page_(&page),
      owner_(owner),
      ad_frame_type_(mojom::blink::AdFrameType::kNonAd),
      client_(client),
      window_proxy_manager_(window_proxy_manager),
      parent_(parent),
      navigation_rate_limiter_(*this),
      window_agent_factory_(inheriting_agent_factory
                                ? inheriting_agent_factory
                                : MakeGarbageCollected<WindowAgentFactory>()),
      is_loading_(false),
      devtools_frame_token_(client->GetDevToolsFrameToken()),
      frame_token_(frame_token) {
  InstanceCounters::IncrementCounter(InstanceCounters::kFrameCounter);
  if (parent_ && insert_type == FrameInsertType::kInsertInConstructor) {
    parent_->InsertAfter(this, previous_sibling);
  } else {
    CHECK(!previous_sibling);
  }
}

void Frame::Initialize() {
  // This frame must either be local or remote.
  DCHECK_NE(IsLocalFrame(), IsRemoteFrame());

  if (owner_)
    owner_->SetContentFrame(*this);
  else
    page_->SetMainFrame(this);
}

void Frame::FocusImpl() {
  // This uses FocusDocumentView rather than SetFocusedFrame so that blur
  // events are properly dispatched on any currently focused elements.
  // It is currently only used when replicating focus changes for
  // cross-process frames so |notify_embedder| is false to avoid sending
  // DidFocus updates from FocusController to the browser process,
  // which already knows the latest focused frame.
  GetPage()->GetFocusController().FocusDocumentView(
      this, false /* notify_embedder */);
}

void Frame::ApplyFrameOwnerProperties(
    mojom::blink::FrameOwnerPropertiesPtr properties) {
  // At the moment, this is only used to replicate frame owner properties
  // for frames with a remote owner.
  auto* owner = To<RemoteFrameOwner>(Owner());

  owner->SetBrowsingContextContainerName(properties->name);
  owner->SetScrollbarMode(properties->scrollbar_mode);
  owner->SetMarginWidth(properties->margin_width);
  owner->SetMarginHeight(properties->margin_height);
  owner->SetAllowFullscreen(properties->allow_fullscreen);
  owner->SetAllowPaymentRequest(properties->allow_payment_request);
  owner->SetIsDisplayNone(properties->is_display_none);
  owner->SetColorScheme(properties->color_scheme);
  owner->SetRequiredCsp(properties->required_csp);
}

void Frame::InsertAfter(Frame* new_child, Frame* previous_sibling) {
  // Parent must match the one set in the constructor
  CHECK_EQ(new_child->parent_, this);

  Frame* next;
  if (!previous_sibling) {
    // Insert at the beginning if no previous sibling is specified.
    next = first_child_;
    first_child_ = new_child;
  } else {
    DCHECK_EQ(previous_sibling->parent_, this);
    next = previous_sibling->next_sibling_;
    previous_sibling->next_sibling_ = new_child;
    new_child->previous_sibling_ = previous_sibling;
  }

  if (next) {
    new_child->next_sibling_ = next;
    next->previous_sibling_ = new_child;
  } else {
    last_child_ = new_child;
  }

  Tree().InvalidateScopedChildCount();
  GetPage()->IncrementSubframeCount();
}

void Frame::ScheduleFormSubmission(FrameScheduler* scheduler,
                                   FormSubmission* form_submission) {
  form_submit_navigation_task_ = PostCancellableTask(
      *scheduler->GetTaskRunner(TaskType::kDOMManipulation), FROM_HERE,
      WTF::Bind(&FormSubmission::Navigate, WrapPersistent(form_submission)));
}

void Frame::CancelFormSubmission() {
  form_submit_navigation_task_.Cancel();
}

bool Frame::IsFormSubmissionPending() {
  return form_submit_navigation_task_.IsActive();
}

void Frame::FocusPage(LocalFrame* originating_frame) {
  // We only allow focus to move to the |frame|'s page when the request comes
  // from a user gesture. (See https://bugs.webkit.org/show_bug.cgi?id=33389.)
  if (originating_frame &&
      LocalFrame::HasTransientUserActivation(originating_frame)) {
    // Ask the broswer process to focus the page.
    GetPage()->GetChromeClient().FocusPage();

    // Tattle on the frame that called |window.focus()|.
    originating_frame->GetLocalFrameHostRemote().DidCallFocus();
  }

  // Always report the attempt to focus the page to the Chrome client for
  // testing purposes (i.e. see WebViewTest.FocusExistingFrameOnNavigate()).
  GetPage()->GetChromeClient().DidFocusPage();
}

void Frame::SetOpenerDoNotNotify(Frame* opener) {
  if (opener_)
    opener_->opened_frame_tracker_.Remove(this);
  if (opener)
    opener->opened_frame_tracker_.Add(this);
  opener_ = opener;
}

Frame* Frame::Top() {
  Frame* parent;
  for (parent = this; parent->Parent(); parent = parent->Parent()) {
  }
  return parent;
}

bool Frame::Swap(WebFrame* new_web_frame) {
  DCHECK(IsAttached());

  using std::swap;

  // Important: do not cache frame tree pointers (e.g.  `previous_sibling_`,
  // `next_sibling_`, `first_child_`, `last_child_`) here. It is possible for
  // `Detach()` to mutate the frame tree and cause cached values to become
  // invalid.
  FrameOwner* owner = owner_;
  FrameSwapScope frame_swap_scope(owner);
  Page* page = page_;
  AtomicString name = Tree().GetName();

  // TODO(dcheng): This probably isn't necessary if we fix the ordering of
  // events in `Swap()`, e.g. `Detach()` should not happen before
  // `new_web_frame` is swapped in.
  // If there is a local parent, it might incorrectly declare itself complete
  // during the detach phase of this swap. Suppress its completion until swap is
  // over, at which point its completion will be correctly dependent on its
  // newly swapped-in child.
  auto* parent_local_frame = DynamicTo<LocalFrame>(parent_.Get());
  std::unique_ptr<IncrementLoadEventDelayCount> delay_parent_load =
      parent_local_frame ? std::make_unique<IncrementLoadEventDelayCount>(
                               *parent_local_frame->GetDocument())
                         : nullptr;

  // Unload the current Document in this frame: this calls unload handlers,
  // detaches child frames, etc. Since this runs script, make sure this frame
  // wasn't detached before continuing with the swap.
  if (!Detach(FrameDetachType::kSwap)) {
    // If the Swap() fails, it should be because the frame has been detached
    // already. Otherwise the caller will not detach the frame when we return
    // false, and the browser and renderer will disagree about the destruction
    // of |this|.
    CHECK(IsDetached());
    return false;
  }

  // Otherwise, on a successful `Detach()` for swap, `this` is now detached--but
  // crucially--still linked into the frame tree.

  if (provisional_frame_) {
    // `this` is about to be replaced, so if `provisional_frame_` is set, it
    // should match `frame` which is being swapped in.
    DCHECK_EQ(provisional_frame_, WebFrame::ToCoreFrame(*new_web_frame));
    provisional_frame_ = nullptr;
  }

  v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
  WindowProxyManager::GlobalProxyVector global_proxies;
  GetWindowProxyManager()->ReleaseGlobalProxies(global_proxies);

  if (new_web_frame->IsWebRemoteFrame()) {
    CHECK(!WebFrame::ToCoreFrame(*new_web_frame));
    To<WebRemoteFrameImpl>(new_web_frame)
        ->InitializeCoreFrame(*page, owner, WebFrame::FromCoreFrame(parent_),
                              nullptr, FrameInsertType::kInsertLater, name,
                              &window_agent_factory());
    // At this point, a `RemoteFrame` will have already updated
    // `Page::MainFrame()` or `FrameOwner::ContentFrame()` as appropriate, and
    // its `parent_` pointer is also populated.
  } else {
    // This is local frame created by `WebLocalFrame::CreateProvisional()`. The
    // `parent` pointer was set when it was constructed; however,
    // `Page::MainFrame()` or `FrameOwner::ContentFrame()` updates are deferred
    // until after `new_frame` is linked into the frame tree.
    // TODO(dcheng): Make local and remote frame updates more uniform.
  }

  Frame* new_frame = WebFrame::ToCoreFrame(*new_web_frame);
  CHECK(new_frame);

  // At this point, `new_frame->parent_` is correctly set, but `new_frame`'s
  // sibling pointers are both still null and not yet updated. In addition, the
  // parent frame (if any) still has not updated its `first_child_` and
  // `last_child_` pointers.
  CHECK_EQ(new_frame->parent_, parent_);
  CHECK(!new_frame->previous_sibling_);
  CHECK(!new_frame->next_sibling_);
  if (previous_sibling_) {
    previous_sibling_->next_sibling_ = new_frame;
  }
  swap(previous_sibling_, new_frame->previous_sibling_);
  if (next_sibling_) {
    next_sibling_->previous_sibling_ = new_frame;
  }
  swap(next_sibling_, new_frame->next_sibling_);

  if (parent_) {
    if (parent_->first_child_ == this) {
      parent_->first_child_ = new_frame;
    }
    if (parent_->last_child_ == this) {
      parent_->last_child_ = new_frame;
    }
    // Not strictly necessary, but keep state as self-consistent as possible.
    parent_ = nullptr;
  }

  if (Frame* opener = opener_) {
    SetOpenerDoNotNotify(nullptr);
    new_frame->SetOpenerDoNotNotify(opener);
  }
  opened_frame_tracker_.TransferTo(new_frame);

  // Clone the state of the current Frame into the one being swapped in.
  if (auto* new_local_frame = DynamicTo<LocalFrame>(new_frame)) {
    // A `LocalFrame` being swapped in is created provisionally, so
    // `Page::MainFrame()` or `FrameOwner::ContentFrame()` needs to be updated
    // to point to the newly swapped-in frame.
    DCHECK_EQ(owner, new_local_frame->Owner());
    if (owner) {
      owner->SetContentFrame(*new_local_frame);

      if (auto* frame_owner_element = DynamicTo<HTMLFrameOwnerElement>(owner)) {
        frame_owner_element->SetEmbeddedContentView(new_local_frame->View());
      }
    } else {
      Page* other_page = new_local_frame->GetPage();
      other_page->SetMainFrame(new_local_frame);
      // This trace event is needed to detect the main frame of the
      // renderer in telemetry metrics. See crbug.com/692112#c11.
      TRACE_EVENT_INSTANT1("loading", "markAsMainFrame",
                           TRACE_EVENT_SCOPE_THREAD, "frame",
                           ::blink::ToTraceValue(new_local_frame));
    }
  }

  new_frame->GetWindowProxyManager()->SetGlobalProxies(global_proxies);

  if (auto* frame_owner_element = DynamicTo<HTMLFrameOwnerElement>(owner)) {
    if (auto* new_local_frame = DynamicTo<LocalFrame>(new_frame)) {
      probe::FrameOwnerContentUpdated(new_local_frame, frame_owner_element);
    } else if (auto* old_local_frame = DynamicTo<LocalFrame>(this)) {
      // TODO(dcheng): What is this probe for? Shouldn't it happen *before*
      // detach?
      probe::FrameOwnerContentUpdated(old_local_frame, frame_owner_element);
    }
  }

  return true;
}

void Frame::RemoveChild(Frame* child) {
  CHECK_EQ(child->parent_, this);
  child->parent_ = nullptr;

  if (first_child_ == child) {
    first_child_ = child->next_sibling_;
  } else {
    CHECK(child->previous_sibling_)
        << " child " << child << " child->previous_sibling_ "
        << child->previous_sibling_;
    child->previous_sibling_->next_sibling_ = child->next_sibling_;
  }

  if (last_child_ == child) {
    last_child_ = child->previous_sibling_;
  } else {
    CHECK(child->next_sibling_);
    child->next_sibling_->previous_sibling_ = child->previous_sibling_;
  }

  child->previous_sibling_ = child->next_sibling_ = nullptr;

  Tree().InvalidateScopedChildCount();
  GetPage()->DecrementSubframeCount();
}

void Frame::DetachFromParent() {
  if (!Parent())
    return;

  // TODO(dcheng): This should really just check if there's a parent, and call
  // RemoveChild() if so. Once provisional frames are removed, this check can be
  // simplified to just check Parent(). See https://crbug.com/578349.
  if (auto* local_frame = DynamicTo<LocalFrame>(this)) {
    if (local_frame->IsProvisional()) {
      return;
    }
  }
  Parent()->RemoveChild(this);
}

STATIC_ASSERT_ENUM(FrameDetachType::kRemove,
                   WebRemoteFrameClient::DetachType::kRemove);
STATIC_ASSERT_ENUM(FrameDetachType::kSwap,
                   WebRemoteFrameClient::DetachType::kSwap);

}  // namespace blink
