// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_HTML_PORTAL_ELEMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_HTML_PORTAL_ELEMENT_H_

#include "base/optional.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "third_party/blink/public/common/tokens/tokens.h"
#include "third_party/blink/public/mojom/portal/portal.mojom-blink-forward.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"

namespace blink {

class Document;
class PortalActivateOptions;
class PortalContents;
class PostMessageOptions;
class ScriptState;

// The HTMLPortalElement implements the <portal> HTML element. The portal
// element can be used to embed another top-level browsing context, which can be
// activated using script. The portal element is still under development and not
// part of the HTML standard. It can be enabled by passing
// --enable-features=Portals. See also https://github.com/WICG/portals.
class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement {
  DEFINE_WRAPPERTYPEINFO();

 public:
  // |portal_token|, |remote_portal| and |portal_client_receiver| are all empty
  // when an empty HTMLPortalElement is constructed, (it hasn't yet been
  // attached to an actual contents).
  explicit HTMLPortalElement(
      Document& document,
      const PortalToken* portal_token = nullptr,
      mojo::PendingAssociatedRemote<mojom::blink::Portal> remote_portal = {},
      mojo::PendingAssociatedReceiver<mojom::blink::PortalClient>
          portal_client_receiver = {});
  ~HTMLPortalElement() override;

  bool IsHTMLPortalElement() const final { return true; }

  // ScriptWrappable overrides.
  void Trace(Visitor* visitor) const override;

  // idl implementation.
  ScriptPromise activate(ScriptState*, PortalActivateOptions*, ExceptionState&);
  void postMessage(ScriptState* script_state,
                   const ScriptValue& message,
                   const PostMessageOptions* options,
                   ExceptionState& exception_state);
  EventListener* onmessage();
  void setOnmessage(EventListener* listener);
  EventListener* onmessageerror();
  void setOnmessageerror(EventListener* listener);

  const PortalToken& GetToken() const;

  mojom::blink::FrameOwnerElementType OwnerType() const override {
    return mojom::blink::FrameOwnerElementType::kPortal;
  }

  // Consumes the portal interface. When a Portal is activated, or if the
  // renderer receives a connection error, this function will gracefully
  // terminate the portal interface.
  void ConsumePortal();

  // Invoked when this element should no longer keep its guest contents alive
  // due to recent adoption.
  void ExpireAdoptionLifetime();

  // Called by PortalContents when it is about to be destroyed.
  void PortalContentsWillBeDestroyed(PortalContents*);

 private:
  // Returns a null string if the checks passed, and a suitable error otherwise.
  String PreActivateChecksCommon();

  // Performs a default activation (e.g. due to an unprevented click), as
  // opposed to one requested by invoking HTMLPortalElement::activate.
  void ActivateDefault();

  // Checks whether the Portals feature is enabled for this document, and logs a
  // warning to the developer if not. Doing basically anything with an
  // HTMLPortalElement in a document which doesn't support portals is forbidden.
  bool CheckPortalsEnabledOrWarn() const;
  bool CheckPortalsEnabledOrThrow(ExceptionState&) const;

  // Checks if, when inserted, we were beyond the frame limit. If so, we will
  // disable navigating the portal and insertion (and will display a warning in
  // the console).
  bool CheckWithinFrameLimitOrWarn() const;

  // Checks that the number of frames and portals on the page are within the
  // limit.
  bool IsCurrentlyWithinFrameLimit() const;

  enum class GuestContentsEligibility {
    // Can have a guest contents.
    kEligible,

    // Ineligible as it is not top-level.
    kNotTopLevel,

    // Ineligible as it is sandboxed.
    kSandboxed,

    // Ineligible as the host's protocol is not in the HTTP family.
    kNotHTTPFamily,

    // Ineligible for additional reasons.
    kIneligible,
  };
  GuestContentsEligibility GetGuestContentsEligibility() const;
  bool CanHaveGuestContents() const {
    return GetGuestContentsEligibility() == GuestContentsEligibility::kEligible;
  }

  // Navigates the portal to |url_|.
  void Navigate();

  // Node overrides
  InsertionNotificationRequest InsertedInto(ContainerNode&) override;
  void RemovedFrom(ContainerNode&) override;
  void DefaultEventHandler(Event&) override;

  // Element overrides
  bool IsURLAttribute(const Attribute&) const override;
  void ParseAttribute(const AttributeModificationParams&) override;
  LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
  bool SupportsFocus() const override;

  // HTMLFrameOwnerElement overrides
  void DisconnectContentFrame() override;
  ParsedFeaturePolicy ConstructContainerPolicy() const override {
    return ParsedFeaturePolicy();
  }
  void AttachLayoutTree(AttachContext& context) override;
  network::mojom::ReferrerPolicy ReferrerPolicyAttribute() override;

  Member<PortalContents> portal_;

  network::mojom::ReferrerPolicy referrer_policy_ =
      network::mojom::ReferrerPolicy::kDefault;

  // Temporarily set to keep this element alive after adoption.
  bool was_just_adopted_ = false;

  // Disable BackForwardCache when using the portal feature, because we do not
  // handle the state inside the portal after putting the page in cache.
  FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle
      feature_handle_for_scheduler_;
};

// Type casting. Custom since adoption could lead to an HTMLPortalElement ending
// up in a document that doesn't have Portals enabled.
template <>
struct DowncastTraits<HTMLPortalElement> {
  static bool AllowFrom(const HTMLElement& element) {
    return element.IsHTMLPortalElement();
  }
  static bool AllowFrom(const Node& node) {
    if (const HTMLElement* html_element = DynamicTo<HTMLElement>(node))
      return html_element->IsHTMLPortalElement();
    return false;
  }
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_HTML_PORTAL_ELEMENT_H_
