Roll src/third_party/WebKit 7f6ef42:d7831f5 (svn 198292:198296)
[chromium-blink-merge.git] / mandoline / tab / frame.cc
blob78a781efec5e97023f8126a863f28aba17a55235
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"
7 #include <algorithm>
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"
16 using mojo::View;
18 DECLARE_VIEW_PROPERTY_TYPE(mandoline::Frame*);
20 namespace mandoline {
22 // Used to find the Frame associated with a View.
23 DEFINE_LOCAL_VIEW_PROPERTY_KEY(Frame*, kFrame, nullptr);
25 namespace {
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();
37 } // namespace
39 Frame::Frame(FrameTree* tree,
40 View* view,
41 ViewOwnership view_ownership,
42 FrameTreeClient* frame_tree_client,
43 scoped_ptr<FrameUserData> user_data)
44 : tree_(tree),
45 view_(view),
46 parent_(nullptr),
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);
55 Frame::~Frame() {
56 if (view_)
57 view_->RemoveObserver(this);
58 while (!children_.empty())
59 delete children_[0];
60 if (parent_)
61 parent_->Remove(this);
62 if (view_)
63 view_->ClearLocalProperty(kFrame);
64 if (view_ownership_ == ViewOwnership::OWNS_VIEW)
65 view_->Destroy();
68 void Frame::Init(Frame* parent) {
69 if (parent)
70 parent->Add(this);
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());
85 // static
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())
94 return this;
96 for (const Frame* child : children_) {
97 const Frame* match = child->FindFrame(id);
98 if (match)
99 return match;
101 return nullptr;
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)
138 return;
140 if (source != 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)
149 return;
151 if (source != 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) {
159 if (parent_)
160 parent_->Remove(this);
162 // Reset |view_ownership_| so we don't attempt to delete |view_| in the
163 // destructor.
164 view_ownership_ = ViewOwnership::DOESNT_OWN_VIEW;
166 // Assume the view associated with the root is never deleted out from under
167 // us.
168 // TODO(sky): Change browser to create a child for each FrameTree.
169 if (tree_->root() == this) {
170 view_->RemoveObserver(this);
171 view_ = nullptr;
172 return;
175 delete this;
178 void Frame::PostMessageEventToFrame(uint32_t frame_id, MessageEventPtr event) {
179 Frame* target = tree_->root()->FindFrame(frame_id);
180 if (!target ||
181 !tree_->delegate_->CanPostMessageEventToFrame(this, target, event.get()))
182 return;
184 NOTIMPLEMENTED();
187 void Frame::NavigateFrame(uint32_t frame_id) {
188 NOTIMPLEMENTED();
191 void Frame::ReloadFrame(uint32_t frame_id) {
192 NOTIMPLEMENTED();
195 } // namespace mandoline