1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "mandoline/tab/frame.h"
9 #include "base/stl_util.h"
10 #include "components/view_manager/public/cpp/view.h"
11 #include "components/view_manager/public/cpp/view_property.h"
12 #include "mandoline/tab/frame_tree.h"
13 #include "mandoline/tab/frame_tree_delegate.h"
14 #include "mandoline/tab/frame_user_data.h"
18 DECLARE_VIEW_PROPERTY_TYPE(mandoline::Frame
*);
22 // Used to find the Frame associated with a View.
23 DEFINE_LOCAL_VIEW_PROPERTY_KEY(Frame
*, kFrame
, nullptr);
27 const uint32_t kNoParentId
= 0u;
29 FrameDataPtr
FrameToFrameData(const Frame
* frame
) {
30 FrameDataPtr
frame_data(FrameData::New());
31 frame_data
->frame_id
= frame
->view()->id();
32 frame_data
->parent_id
=
33 frame
->parent() ? frame
->parent()->view()->id() : kNoParentId
;
34 return frame_data
.Pass();
39 Frame::Frame(FrameTree
* tree
,
41 ViewOwnership view_ownership
,
42 FrameTreeClient
* frame_tree_client
,
43 scoped_ptr
<FrameUserData
> user_data
)
47 view_ownership_(view_ownership
),
48 user_data_(user_data
.Pass()),
49 frame_tree_client_(frame_tree_client
),
50 frame_tree_server_binding_(this) {
51 view_
->SetLocalProperty(kFrame
, this);
52 view_
->AddObserver(this);
57 view_
->RemoveObserver(this);
58 while (!children_
.empty())
61 parent_
->Remove(this);
63 view_
->ClearLocalProperty(kFrame
);
64 if (view_ownership_
== ViewOwnership::OWNS_VIEW
)
68 void Frame::Init(Frame
* parent
) {
72 std::vector
<const Frame
*> frames
;
73 tree_
->root()->BuildFrameTree(&frames
);
75 mojo::Array
<FrameDataPtr
> array(frames
.size());
76 for (size_t i
= 0; i
< frames
.size(); ++i
)
77 array
[i
] = FrameToFrameData(frames
[i
]).Pass();
79 // TODO(sky): error handling.
80 FrameTreeServerPtr frame_tree_server_ptr
;
81 frame_tree_server_binding_
.Bind(GetProxy(&frame_tree_server_ptr
).Pass());
82 frame_tree_client_
->OnConnect(frame_tree_server_ptr
.Pass(), array
.Pass());
86 Frame
* Frame::FindFirstFrameAncestor(View
* view
) {
87 while (view
&& !view
->GetLocalProperty(kFrame
))
88 view
= view
->parent();
89 return view
? view
->GetLocalProperty(kFrame
) : nullptr;
92 const Frame
* Frame::FindFrame(uint32_t id
) const {
93 if (id
== view_
->id())
96 for (const Frame
* child
: children_
) {
97 const Frame
* match
= child
->FindFrame(id
);
104 bool Frame::HasAncestor(const Frame
* frame
) const {
105 const Frame
* current
= this;
106 while (current
&& current
!= frame
)
107 current
= current
->parent_
;
108 return current
== frame
;
111 void Frame::BuildFrameTree(std::vector
<const Frame
*>* frames
) const {
112 frames
->push_back(this);
113 for (const Frame
* frame
: children_
)
114 frame
->BuildFrameTree(frames
);
117 void Frame::Add(Frame
* node
) {
118 DCHECK(!node
->parent_
);
120 node
->parent_
= this;
121 children_
.push_back(node
);
123 tree_
->root()->NotifyAdded(this, node
);
126 void Frame::Remove(Frame
* node
) {
127 DCHECK_EQ(node
->parent_
, this);
128 auto iter
= std::find(children_
.begin(), children_
.end(), node
);
129 DCHECK(iter
!= children_
.end());
130 node
->parent_
= nullptr;
131 children_
.erase(iter
);
133 tree_
->root()->NotifyRemoved(this, node
);
136 void Frame::NotifyAdded(const Frame
* source
, const Frame
* added_node
) {
137 if (added_node
== this)
141 frame_tree_client_
->OnFrameAdded(FrameToFrameData(added_node
));
143 for (Frame
* child
: children_
)
144 child
->NotifyAdded(source
, added_node
);
147 void Frame::NotifyRemoved(const Frame
* source
, const Frame
* removed_node
) {
148 if (removed_node
== this)
152 frame_tree_client_
->OnFrameRemoved(removed_node
->view_
->id());
154 for (Frame
* child
: children_
)
155 child
->NotifyRemoved(source
, removed_node
);
158 void Frame::OnViewDestroying(mojo::View
* view
) {
160 parent_
->Remove(this);
162 // Reset |view_ownership_| so we don't attempt to delete |view_| in the
164 view_ownership_
= ViewOwnership::DOESNT_OWN_VIEW
;
166 // Assume the view associated with the root is never deleted out from under
168 // TODO(sky): Change browser to create a child for each FrameTree.
169 if (tree_
->root() == this) {
170 view_
->RemoveObserver(this);
178 void Frame::PostMessageEventToFrame(uint32_t frame_id
, MessageEventPtr event
) {
179 Frame
* target
= tree_
->root()->FindFrame(frame_id
);
181 !tree_
->delegate_
->CanPostMessageEventToFrame(this, target
, event
.get()))
187 void Frame::NavigateFrame(uint32_t frame_id
) {
191 void Frame::ReloadFrame(uint32_t frame_id
) {
195 } // namespace mandoline