| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "components/web_view/web_view_impl.h" | |
| 6 | |
| 7 #include <queue> | |
| 8 #include <utility> | |
| 9 | |
| 10 #include "base/bind.h" | |
| 11 #include "base/command_line.h" | |
| 12 #include "components/mus/public/cpp/scoped_window_ptr.h" | |
| 13 #include "components/mus/public/cpp/window.h" | |
| 14 #include "components/mus/public/cpp/window_tree_connection.h" | |
| 15 #include "components/web_view/client_initiated_frame_connection.h" | |
| 16 #include "components/web_view/frame.h" | |
| 17 #include "components/web_view/frame_connection.h" | |
| 18 #include "components/web_view/frame_devtools_agent.h" | |
| 19 #include "components/web_view/frame_tree.h" | |
| 20 #include "components/web_view/navigation_entry.h" | |
| 21 #include "components/web_view/pending_web_view_load.h" | |
| 22 #include "components/web_view/url_request_cloneable.h" | |
| 23 #include "mojo/converters/geometry/geometry_type_converters.h" | |
| 24 #include "mojo/shell/public/cpp/shell.h" | |
| 25 #include "url/gurl.h" | |
| 26 | |
| 27 namespace web_view { | |
| 28 | |
| 29 using web_view::mojom::ButtonState; | |
| 30 | |
| 31 //////////////////////////////////////////////////////////////////////////////// | |
| 32 // WebViewImpl, public: | |
| 33 | |
| 34 WebViewImpl::WebViewImpl(mojo::Shell* shell, | |
| 35 mojom::WebViewClientPtr client, | |
| 36 mojo::InterfaceRequest<mojom::WebView> request) | |
| 37 : shell_(shell), | |
| 38 client_(std::move(client)), | |
| 39 binding_(this, std::move(request)), | |
| 40 root_(nullptr), | |
| 41 content_(nullptr), | |
| 42 find_controller_(this), | |
| 43 navigation_controller_(this) { | |
| 44 devtools_agent_.reset(new FrameDevToolsAgent(shell_, this)); | |
| 45 OnDidNavigate(); | |
| 46 } | |
| 47 | |
| 48 WebViewImpl::~WebViewImpl() { | |
| 49 if (content_) | |
| 50 content_->RemoveObserver(this); | |
| 51 if (root_) { | |
| 52 root_->RemoveObserver(this); | |
| 53 mus::ScopedWindowPtr::DeleteWindowOrWindowManager(root_); | |
| 54 } | |
| 55 } | |
| 56 | |
| 57 void WebViewImpl::OnLoad(const GURL& pending_url) { | |
| 58 // Frames are uniqued based on the id of the associated Window. By creating a | |
| 59 // new Window each time through we ensure the renderers get a clean id, rather | |
| 60 // than one they may know about and try to incorrectly use. | |
| 61 if (content_) { | |
| 62 content_->Destroy(); | |
| 63 DCHECK(!content_); | |
| 64 } | |
| 65 | |
| 66 client_->TopLevelNavigationStarted(pending_url.spec()); | |
| 67 | |
| 68 content_ = root_->connection()->NewWindow(); | |
| 69 content_->SetBounds(gfx::Rect(root_->bounds().size())); | |
| 70 root_->AddChild(content_); | |
| 71 content_->SetVisible(true); | |
| 72 content_->AddObserver(this); | |
| 73 | |
| 74 scoped_ptr<PendingWebViewLoad> pending_load(std::move(pending_load_)); | |
| 75 scoped_ptr<FrameConnection> frame_connection( | |
| 76 pending_load->frame_connection()); | |
| 77 mus::mojom::WindowTreeClientPtr window_tree_client = | |
| 78 frame_connection->GetWindowTreeClient(); | |
| 79 | |
| 80 Frame::ClientPropertyMap client_properties; | |
| 81 if (devtools_agent_) { | |
| 82 devtools_service::DevToolsAgentPtr forward_agent; | |
| 83 frame_connection->connection()->ConnectToService(&forward_agent); | |
| 84 devtools_agent_->AttachFrame(std::move(forward_agent), &client_properties); | |
| 85 } | |
| 86 | |
| 87 mojom::FrameClient* frame_client = frame_connection->frame_client(); | |
| 88 const uint32_t content_handler_id = frame_connection->GetContentHandlerID(); | |
| 89 frame_tree_.reset( | |
| 90 new FrameTree(content_handler_id, content_, std::move(window_tree_client), | |
| 91 this, frame_client, std::move(frame_connection), | |
| 92 client_properties, pending_load->navigation_start_time())); | |
| 93 } | |
| 94 | |
| 95 void WebViewImpl::PreOrderDepthFirstTraverseTree(Frame* node, | |
| 96 std::vector<Frame*>* output) { | |
| 97 output->push_back(node); | |
| 98 for (Frame* child : node->children()) | |
| 99 PreOrderDepthFirstTraverseTree(child, output); | |
| 100 } | |
| 101 | |
| 102 //////////////////////////////////////////////////////////////////////////////// | |
| 103 // WebViewImpl, WebView implementation: | |
| 104 | |
| 105 void WebViewImpl::LoadRequest(mojo::URLRequestPtr request) { | |
| 106 navigation_controller_.LoadURL(std::move(request)); | |
| 107 } | |
| 108 | |
| 109 void WebViewImpl::GetWindowTreeClient( | |
| 110 mojo::InterfaceRequest<mus::mojom::WindowTreeClient> window_tree_client) { | |
| 111 mus::WindowTreeConnection::Create( | |
| 112 this, std::move(window_tree_client), | |
| 113 mus::WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); | |
| 114 } | |
| 115 | |
| 116 void WebViewImpl::Find(const mojo::String& search_text, | |
| 117 bool forward_direction) { | |
| 118 find_controller_.Find(search_text.To<std::string>(), forward_direction); | |
| 119 } | |
| 120 | |
| 121 void WebViewImpl::StopFinding() { | |
| 122 find_controller_.StopFinding(); | |
| 123 } | |
| 124 | |
| 125 void WebViewImpl::GoBack() { | |
| 126 if (!navigation_controller_.CanGoBack()) | |
| 127 return; | |
| 128 navigation_controller_.GoBack(); | |
| 129 } | |
| 130 | |
| 131 void WebViewImpl::GoForward() { | |
| 132 if (!navigation_controller_.CanGoForward()) | |
| 133 return; | |
| 134 navigation_controller_.GoForward(); | |
| 135 } | |
| 136 | |
| 137 //////////////////////////////////////////////////////////////////////////////// | |
| 138 // WebViewImpl, mus::WindowTreeDelegate implementation: | |
| 139 | |
| 140 void WebViewImpl::OnEmbed(mus::Window* root) { | |
| 141 // We must have been granted embed root priviledges, otherwise we can't | |
| 142 // Embed() in any descendants. | |
| 143 DCHECK(root->connection()->IsEmbedRoot()); | |
| 144 root->AddObserver(this); | |
| 145 root_ = root; | |
| 146 | |
| 147 if (pending_load_ && pending_load_->is_content_handler_id_valid()) | |
| 148 OnLoad(pending_load_->pending_url()); | |
| 149 } | |
| 150 | |
| 151 void WebViewImpl::OnConnectionLost(mus::WindowTreeConnection* connection) { | |
| 152 root_ = nullptr; | |
| 153 } | |
| 154 | |
| 155 //////////////////////////////////////////////////////////////////////////////// | |
| 156 // WebViewImpl, mus::WindowObserver implementation: | |
| 157 | |
| 158 void WebViewImpl::OnWindowBoundsChanged(mus::Window* window, | |
| 159 const gfx::Rect& old_bounds, | |
| 160 const gfx::Rect& new_bounds) { | |
| 161 if (window != content_ && content_) | |
| 162 content_->SetBounds(gfx::Rect(new_bounds.size())); | |
| 163 } | |
| 164 | |
| 165 void WebViewImpl::OnWindowDestroyed(mus::Window* window) { | |
| 166 // |FrameTree| cannot outlive the content window. | |
| 167 if (window == content_) { | |
| 168 frame_tree_.reset(); | |
| 169 content_ = nullptr; | |
| 170 } | |
| 171 } | |
| 172 | |
| 173 //////////////////////////////////////////////////////////////////////////////// | |
| 174 // WebViewImpl, FrameTreeDelegate implementation: | |
| 175 | |
| 176 scoped_ptr<FrameUserData> WebViewImpl::CreateUserDataForNewFrame( | |
| 177 mojom::FrameClientPtr frame_client) { | |
| 178 return make_scoped_ptr( | |
| 179 new ClientInitiatedFrameConnection(std::move(frame_client))); | |
| 180 } | |
| 181 | |
| 182 bool WebViewImpl::CanPostMessageEventToFrame(const Frame* source, | |
| 183 const Frame* target, | |
| 184 mojom::HTMLMessageEvent* event) { | |
| 185 return true; | |
| 186 } | |
| 187 | |
| 188 void WebViewImpl::LoadingStateChanged(bool loading, double progress) { | |
| 189 client_->LoadingStateChanged(loading, progress); | |
| 190 } | |
| 191 | |
| 192 void WebViewImpl::TitleChanged(const mojo::String& title) { | |
| 193 client_->TitleChanged(title); | |
| 194 } | |
| 195 | |
| 196 void WebViewImpl::NavigateTopLevel(Frame* source, mojo::URLRequestPtr request) { | |
| 197 client_->TopLevelNavigateRequest(std::move(request)); | |
| 198 } | |
| 199 | |
| 200 void WebViewImpl::CanNavigateFrame(Frame* target, | |
| 201 mojo::URLRequestPtr request, | |
| 202 const CanNavigateFrameCallback& callback) { | |
| 203 FrameConnection::CreateConnectionForCanNavigateFrame( | |
| 204 shell_, target, std::move(request), callback); | |
| 205 } | |
| 206 | |
| 207 void WebViewImpl::DidStartNavigation(Frame* frame) {} | |
| 208 | |
| 209 void WebViewImpl::DidCommitProvisionalLoad(Frame* frame) { | |
| 210 navigation_controller_.FrameDidCommitProvisionalLoad(frame); | |
| 211 } | |
| 212 | |
| 213 void WebViewImpl::DidNavigateLocally(Frame* source, | |
| 214 const GURL& url) { | |
| 215 navigation_controller_.FrameDidNavigateLocally(source, url); | |
| 216 if (source == frame_tree_->root()) | |
| 217 client_->TopLevelNavigationStarted(url.spec()); | |
| 218 } | |
| 219 | |
| 220 void WebViewImpl::DidDestroyFrame(Frame* frame) { | |
| 221 find_controller_.DidDestroyFrame(frame); | |
| 222 } | |
| 223 | |
| 224 void WebViewImpl::OnFindInFrameCountUpdated(int32_t request_id, | |
| 225 Frame* frame, | |
| 226 int32_t count, | |
| 227 bool final_update) { | |
| 228 find_controller_.OnFindInFrameCountUpdated(request_id, frame, count, | |
| 229 final_update); | |
| 230 } | |
| 231 | |
| 232 void WebViewImpl::OnFindInPageSelectionUpdated(int32_t request_id, | |
| 233 Frame* frame, | |
| 234 int32_t active_match_ordinal) { | |
| 235 find_controller_.OnFindInPageSelectionUpdated(request_id, frame, | |
| 236 active_match_ordinal); | |
| 237 } | |
| 238 | |
| 239 //////////////////////////////////////////////////////////////////////////////// | |
| 240 // WebViewImpl, FrameDevToolsAgentDelegate implementation: | |
| 241 | |
| 242 void WebViewImpl::HandlePageNavigateRequest(const GURL& url) { | |
| 243 mojo::URLRequestPtr request(mojo::URLRequest::New()); | |
| 244 request->url = url.spec(); | |
| 245 client_->TopLevelNavigateRequest(std::move(request)); | |
| 246 } | |
| 247 | |
| 248 //////////////////////////////////////////////////////////////////////////////// | |
| 249 // WebViewImpl, NavigationControllerDelegate implementation: | |
| 250 | |
| 251 void WebViewImpl::OnNavigate(mojo::URLRequestPtr request) { | |
| 252 pending_load_.reset(new PendingWebViewLoad(this)); | |
| 253 pending_load_->Init(std::move(request)); | |
| 254 } | |
| 255 | |
| 256 void WebViewImpl::OnDidNavigate() { | |
| 257 client_->BackForwardChanged( | |
| 258 navigation_controller_.CanGoBack() ? ButtonState::ENABLED | |
| 259 : ButtonState::DISABLED, | |
| 260 navigation_controller_.CanGoForward() ? ButtonState::ENABLED | |
| 261 : ButtonState::DISABLED); | |
| 262 } | |
| 263 | |
| 264 //////////////////////////////////////////////////////////////////////////////// | |
| 265 // WebViewImpl, FindControllerDelegate implementation: | |
| 266 | |
| 267 std::vector<Frame*> WebViewImpl::GetAllFrames() { | |
| 268 std::vector<Frame*> all_frames; | |
| 269 PreOrderDepthFirstTraverseTree(frame_tree_->root(), &all_frames); | |
| 270 return all_frames; | |
| 271 } | |
| 272 | |
| 273 mojom::WebViewClient* WebViewImpl::GetWebViewClient() { | |
| 274 return client_.get(); | |
| 275 } | |
| 276 | |
| 277 } // namespace web_view | |
| OLD | NEW |