Commit 7bf88e6e authored by Lucas Furukawa Gadani's avatar Lucas Furukawa Gadani Committed by Commit Bot

Portals: Notify the Document when a portal is created or destroyed.

This CL also adds an API to retrieve the portal given a portal token.

Bug: 865565
Change-Id: Ie8f5e8f5aaea395811e9da3afc04fc89df48196b
Reviewed-on: https://chromium-review.googlesource.com/c/1297248Reviewed-by: default avatarJeremy Roman <jbroman@chromium.org>
Commit-Queue: Lucas Gadani <lfg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#604410}
parent fe0f32e2
......@@ -500,6 +500,8 @@ blink_core_sources("html") {
"media/picture_in_picture_interstitial.h",
"plugin_document.cc",
"plugin_document.h",
"portal/document_portals.cc",
"portal/document_portals.h",
"portal/html_portal_element.cc",
"portal/html_portal_element.h",
"rel_list.cc",
......
// 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.
#include "third_party/blink/renderer/core/html/portal/document_portals.h"
#include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
namespace blink {
// static
const char DocumentPortals::kSupplementName[] = "DocumentPortals";
// static
DocumentPortals& DocumentPortals::From(Document& document) {
DocumentPortals* supplement =
Supplement<Document>::From<DocumentPortals>(document);
if (!supplement) {
supplement = new DocumentPortals(document);
Supplement<Document>::ProvideTo(document, supplement);
}
return *supplement;
}
DocumentPortals::DocumentPortals(Document& document)
: Supplement<Document>(document) {}
void DocumentPortals::OnPortalInserted(HTMLPortalElement* portal) {
portals_.push_back(portal);
}
void DocumentPortals::OnPortalRemoved(HTMLPortalElement* portal) {
portals_.EraseAt(portals_.Find(portal));
}
HTMLPortalElement* DocumentPortals::GetPortal(
const base::UnguessableToken& token) const {
for (HTMLPortalElement* portal : portals_) {
if (portal->GetToken() == token)
return portal;
}
return nullptr;
}
void DocumentPortals::Trace(Visitor* visitor) {
Supplement<Document>::Trace(visitor);
visitor->Trace(portals_);
}
} // namespace blink
// 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_DOCUMENT_PORTALS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_DOCUMENT_PORTALS_H_
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/supplementable.h"
namespace blink {
class HTMLPortalElement;
class DocumentPortals : public GarbageCollected<DocumentPortals>,
public Supplement<Document> {
public:
static const char kSupplementName[];
static DocumentPortals& From(Document&);
// Used to notify the document that a portal was inserted.
void OnPortalInserted(HTMLPortalElement* portal);
// Notifies that a portal was removed from the Document.
void OnPortalRemoved(HTMLPortalElement* portal);
// Retrieves the portal identified by the token.
HTMLPortalElement* GetPortal(const base::UnguessableToken&) const;
void Trace(Visitor*) override;
private:
explicit DocumentPortals(Document&);
HeapVector<Member<HTMLPortalElement>> portals_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_DOCUMENT_PORTALS_H_
......@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/html_unknown_element.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/html/portal/document_portals.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
......@@ -85,6 +86,7 @@ HTMLPortalElement::InsertionNotificationRequest HTMLPortalElement::InsertedInto(
[](HTMLPortalElement* portal,
const base::UnguessableToken& portal_token) {
portal->portal_token_ = portal_token;
DocumentPortals::From(portal->GetDocument()).OnPortalInserted(portal);
},
WrapPersistent(this)));
Navigate();
......@@ -99,6 +101,14 @@ void HTMLPortalElement::RemovedFrom(ContainerNode& node) {
Document& document = GetDocument();
if (node.IsInDocumentTree() && document.IsHTMLDocument()) {
// The portal creation is asynchronous, and the Document only gets notified
// after the element receives a callback from the browser that assigns its
// token, so we need to check whether that has been completed before
// notifying the document about the portal's removal.
if (!portal_token_.is_empty())
DocumentPortals::From(GetDocument()).OnPortalRemoved(this);
portal_token_ = base::UnguessableToken();
portal_ptr_.reset();
}
}
......
......@@ -35,6 +35,8 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement {
// idl implementation.
ScriptPromise activate(ScriptState*);
const base::UnguessableToken& GetToken() const { return portal_token_; }
FrameOwnerElementType OwnerType() const override {
return FrameOwnerElementType::kPortal;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment