| 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/html_viewer/html_frame.h" | |
| 6 | |
| 7 #include <stddef.h> | |
| 8 #include <algorithm> | |
| 9 #include <limits> | |
| 10 #include <utility> | |
| 11 | |
| 12 #include "base/bind.h" | |
| 13 #include "base/single_thread_task_runner.h" | |
| 14 #include "base/stl_util.h" | |
| 15 #include "base/strings/string_util.h" | |
| 16 #include "base/thread_task_runner_handle.h" | |
| 17 #include "cc/blink/web_layer_impl.h" | |
| 18 #include "cc/surfaces/surface_id.h" | |
| 19 #include "components/html_viewer/ax_provider_impl.h" | |
| 20 #include "components/html_viewer/blink_basic_type_converters.h" | |
| 21 #include "components/html_viewer/blink_find_type_converters.h" | |
| 22 #include "components/html_viewer/blink_text_input_type_converters.h" | |
| 23 #include "components/html_viewer/blink_url_request_type_converters.h" | |
| 24 #include "components/html_viewer/devtools_agent_impl.h" | |
| 25 #include "components/html_viewer/geolocation_client_impl.h" | |
| 26 #include "components/html_viewer/global_state.h" | |
| 27 #include "components/html_viewer/html_factory.h" | |
| 28 #include "components/html_viewer/html_frame_delegate.h" | |
| 29 #include "components/html_viewer/html_frame_properties.h" | |
| 30 #include "components/html_viewer/html_frame_tree_manager.h" | |
| 31 #include "components/html_viewer/html_widget.h" | |
| 32 #include "components/html_viewer/media_factory.h" | |
| 33 #include "components/html_viewer/stats_collection_controller.h" | |
| 34 #include "components/html_viewer/touch_handler.h" | |
| 35 #include "components/html_viewer/web_layer_tree_view_impl.h" | |
| 36 #include "components/html_viewer/web_storage_namespace_impl.h" | |
| 37 #include "components/html_viewer/web_url_loader_impl.h" | |
| 38 #include "components/mus/public/cpp/scoped_window_ptr.h" | |
| 39 #include "components/mus/public/cpp/window.h" | |
| 40 #include "components/mus/public/cpp/window_tree_connection.h" | |
| 41 #include "components/mus/ws/ids.h" | |
| 42 #include "mojo/common/common_type_converters.h" | |
| 43 #include "mojo/converters/blink/blink_input_events_type_converters.h" | |
| 44 #include "mojo/converters/geometry/geometry_type_converters.h" | |
| 45 #include "mojo/shell/public/cpp/shell.h" | |
| 46 #include "third_party/WebKit/public/platform/Platform.h" | |
| 47 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h" | |
| 48 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" | |
| 49 #include "third_party/WebKit/public/platform/WebSize.h" | |
| 50 #include "third_party/WebKit/public/web/WebConsoleMessage.h" | |
| 51 #include "third_party/WebKit/public/web/WebDocument.h" | |
| 52 #include "third_party/WebKit/public/web/WebElement.h" | |
| 53 #include "third_party/WebKit/public/web/WebFindOptions.h" | |
| 54 #include "third_party/WebKit/public/web/WebFrameOwnerProperties.h" | |
| 55 #include "third_party/WebKit/public/web/WebInputEvent.h" | |
| 56 #include "third_party/WebKit/public/web/WebKit.h" | |
| 57 #include "third_party/WebKit/public/web/WebLocalFrame.h" | |
| 58 #include "third_party/WebKit/public/web/WebNavigationPolicy.h" | |
| 59 #include "third_party/WebKit/public/web/WebRemoteFrame.h" | |
| 60 #include "third_party/WebKit/public/web/WebRemoteFrameClient.h" | |
| 61 #include "third_party/WebKit/public/web/WebScriptSource.h" | |
| 62 #include "third_party/WebKit/public/web/WebView.h" | |
| 63 #include "ui/gfx/geometry/dip_util.h" | |
| 64 #include "ui/gfx/geometry/size.h" | |
| 65 #include "url/gurl.h" | |
| 66 #include "url/origin.h" | |
| 67 #include "url/url_constants.h" | |
| 68 | |
| 69 using mojo::AxProvider; | |
| 70 using mojo::Rect; | |
| 71 using mojo::ServiceProviderPtr; | |
| 72 using mojo::URLResponsePtr; | |
| 73 using web_view::mojom::HTMLMessageEvent; | |
| 74 using web_view::mojom::HTMLMessageEventPtr; | |
| 75 | |
| 76 namespace html_viewer { | |
| 77 namespace { | |
| 78 | |
| 79 const size_t kMaxTitleChars = 4 * 1024; | |
| 80 | |
| 81 web_view::mojom::NavigationTargetType WebNavigationPolicyToNavigationTarget( | |
| 82 blink::WebNavigationPolicy policy) { | |
| 83 switch (policy) { | |
| 84 case blink::WebNavigationPolicyCurrentTab: | |
| 85 return web_view::mojom::NavigationTargetType::EXISTING_FRAME; | |
| 86 case blink::WebNavigationPolicyNewBackgroundTab: | |
| 87 case blink::WebNavigationPolicyNewForegroundTab: | |
| 88 case blink::WebNavigationPolicyNewWindow: | |
| 89 case blink::WebNavigationPolicyNewPopup: | |
| 90 return web_view::mojom::NavigationTargetType::NEW_FRAME; | |
| 91 default: | |
| 92 return web_view::mojom::NavigationTargetType::NO_PREFERENCE; | |
| 93 } | |
| 94 } | |
| 95 | |
| 96 HTMLFrame* GetPreviousSibling(HTMLFrame* frame) { | |
| 97 DCHECK(frame->parent()); | |
| 98 auto iter = std::find(frame->parent()->children().begin(), | |
| 99 frame->parent()->children().end(), frame); | |
| 100 return (iter == frame->parent()->children().begin()) ? nullptr : *(--iter); | |
| 101 } | |
| 102 | |
| 103 // See surface_layer.h for a description of this callback. | |
| 104 void SatisfyCallback(cc::SurfaceSequence sequence) { | |
| 105 // TODO(fsamuel): Implement this. | |
| 106 } | |
| 107 | |
| 108 // See surface_layer.h for a description of this callback. | |
| 109 void RequireCallback(cc::SurfaceId surface_id, | |
| 110 cc::SurfaceSequence sequence) { | |
| 111 // TODO(fsamuel): Implement this. | |
| 112 } | |
| 113 | |
| 114 } // namespace | |
| 115 | |
| 116 HTMLFrame::HTMLFrame(CreateParams* params) | |
| 117 : frame_tree_manager_(params->manager), | |
| 118 parent_(params->parent), | |
| 119 window_(nullptr), | |
| 120 id_(params->id), | |
| 121 web_frame_(nullptr), | |
| 122 delegate_(params->delegate), | |
| 123 pending_navigation_(false), | |
| 124 weak_factory_(this) { | |
| 125 TRACE_EVENT0("html_viewer", "HTMLFrame::HTMLFrame"); | |
| 126 if (parent_) | |
| 127 parent_->children_.push_back(this); | |
| 128 | |
| 129 if (params->window && params->window->id() == id_) | |
| 130 SetWindow(params->window); | |
| 131 | |
| 132 SetReplicatedFrameStateFromClientProperties(params->properties, &state_); | |
| 133 | |
| 134 if (!parent_) { | |
| 135 CreateRootWebWidget(); | |
| 136 | |
| 137 // This is the root of the tree (aka the main frame). | |
| 138 // Expected order for creating webframes is: | |
| 139 // . Create local webframe (first webframe must always be local). | |
| 140 // . Set as main frame on WebView. | |
| 141 // . Swap to remote (if not local). | |
| 142 blink::WebLocalFrame* local_web_frame = | |
| 143 blink::WebLocalFrame::create(state_.tree_scope, this); | |
| 144 // We need to set the main frame before creating children so that state is | |
| 145 // properly set up in blink. | |
| 146 web_view()->setMainFrame(local_web_frame); | |
| 147 | |
| 148 // The resize and setDeviceScaleFactor() needs to be after setting the main | |
| 149 // frame. | |
| 150 const gfx::Size size_in_pixels(params->window->bounds().size()); | |
| 151 const gfx::Size size_in_dips = gfx::ConvertSizeToDIP( | |
| 152 params->window->viewport_metrics().device_pixel_ratio, size_in_pixels); | |
| 153 web_view()->resize(size_in_dips); | |
| 154 web_frame_ = local_web_frame; | |
| 155 web_view()->setDeviceScaleFactor(global_state()->device_pixel_ratio()); | |
| 156 if (id_ != params->window->id()) { | |
| 157 blink::WebRemoteFrame* remote_web_frame = | |
| 158 blink::WebRemoteFrame::create(state_.tree_scope, this); | |
| 159 local_web_frame->swap(remote_web_frame); | |
| 160 web_frame_ = remote_web_frame; | |
| 161 } else { | |
| 162 // Setup a DevTools agent if this is the local main frame and the browser | |
| 163 // side has set relevant client properties. | |
| 164 mojo::Array<uint8_t> devtools_id = | |
| 165 GetValueFromClientProperties("devtools-id", params->properties); | |
| 166 if (!devtools_id.is_null()) { | |
| 167 mojo::Array<uint8_t> devtools_state = | |
| 168 GetValueFromClientProperties("devtools-state", params->properties); | |
| 169 std::string devtools_state_str = devtools_state.To<std::string>(); | |
| 170 devtools_agent_.reset(new DevToolsAgentImpl( | |
| 171 web_frame_->toWebLocalFrame(), devtools_id.To<std::string>(), | |
| 172 devtools_state.is_null() ? nullptr : &devtools_state_str)); | |
| 173 } | |
| 174 | |
| 175 // Collect startup perf data for local main frames in test environments. | |
| 176 // Child frames aren't tracked, and tracking remote frames is redundant. | |
| 177 startup_performance_data_collector_ = | |
| 178 StatsCollectionController::Install(web_frame_, GetShell()); | |
| 179 } | |
| 180 } else if (!params->is_local_create_child && params->window && | |
| 181 id_ == params->window->id()) { | |
| 182 // Frame represents the local frame, and it isn't the root of the tree. | |
| 183 HTMLFrame* previous_sibling = GetPreviousSibling(this); | |
| 184 blink::WebFrame* previous_web_frame = | |
| 185 previous_sibling ? previous_sibling->web_frame() : nullptr; | |
| 186 CHECK(!parent_->IsLocal()); | |
| 187 web_frame_ = parent_->web_frame()->toWebRemoteFrame()->createLocalChild( | |
| 188 state_.tree_scope, state_.name, state_.sandbox_flags, this, | |
| 189 previous_web_frame, | |
| 190 // TODO(lazyboy): Replicate WebFrameOwnerProperties where needed. | |
| 191 blink::WebFrameOwnerProperties()); | |
| 192 CreateLocalRootWebWidget(web_frame_->toWebLocalFrame()); | |
| 193 } else if (!parent_->IsLocal()) { | |
| 194 web_frame_ = parent_->web_frame()->toWebRemoteFrame()->createRemoteChild( | |
| 195 state_.tree_scope, state_.name, state_.sandbox_flags, this); | |
| 196 } else { | |
| 197 CHECK(params->is_local_create_child); | |
| 198 | |
| 199 blink::WebLocalFrame* child_web_frame = | |
| 200 blink::WebLocalFrame::create(state_.tree_scope, this); | |
| 201 web_frame_ = child_web_frame; | |
| 202 parent_->web_frame_->appendChild(child_web_frame); | |
| 203 } | |
| 204 | |
| 205 DVLOG(2) << "HTMLFrame init this=" << this << " id=" << id_ | |
| 206 << " local=" << IsLocal() | |
| 207 << " parent=" << (parent_ ? parent_->id_ : 0u); | |
| 208 | |
| 209 if (!IsLocal()) { | |
| 210 blink::WebRemoteFrame* remote_web_frame = web_frame_->toWebRemoteFrame(); | |
| 211 if (remote_web_frame) { | |
| 212 remote_web_frame->setReplicatedOrigin(state_.origin); | |
| 213 remote_web_frame->setReplicatedName(state_.name); | |
| 214 } | |
| 215 } | |
| 216 } | |
| 217 | |
| 218 void HTMLFrame::Close() { | |
| 219 if (GetWebWidget()) { | |
| 220 // Closing the root widget (WebView) implicitly detaches. For children | |
| 221 // (which have a WebFrameWidget) a detach() is required. Use a temporary | |
| 222 // as if 'this' is the root the call to GetWebWidget()->close() deletes | |
| 223 // 'this'. | |
| 224 const bool is_child = parent_ != nullptr; | |
| 225 GetWebWidget()->close(); | |
| 226 if (is_child) | |
| 227 web_frame_->detach(); | |
| 228 } else { | |
| 229 web_frame_->detach(); | |
| 230 } | |
| 231 } | |
| 232 | |
| 233 const HTMLFrame* HTMLFrame::FindFrame(uint32_t id) const { | |
| 234 if (id == id_) | |
| 235 return this; | |
| 236 | |
| 237 for (const HTMLFrame* child : children_) { | |
| 238 const HTMLFrame* match = child->FindFrame(id); | |
| 239 if (match) | |
| 240 return match; | |
| 241 } | |
| 242 return nullptr; | |
| 243 } | |
| 244 | |
| 245 blink::WebView* HTMLFrame::web_view() { | |
| 246 blink::WebWidget* web_widget = | |
| 247 html_widget_ ? html_widget_->GetWidget() : nullptr; | |
| 248 return web_widget && web_widget->isWebView() | |
| 249 ? static_cast<blink::WebView*>(web_widget) | |
| 250 : nullptr; | |
| 251 } | |
| 252 | |
| 253 blink::WebWidget* HTMLFrame::GetWebWidget() { | |
| 254 return html_widget_ ? html_widget_->GetWidget() : nullptr; | |
| 255 } | |
| 256 | |
| 257 bool HTMLFrame::IsLocal() const { | |
| 258 return web_frame_->isWebLocalFrame(); | |
| 259 } | |
| 260 | |
| 261 bool HTMLFrame::HasLocalDescendant() const { | |
| 262 if (IsLocal()) | |
| 263 return true; | |
| 264 | |
| 265 for (HTMLFrame* child : children_) { | |
| 266 if (child->HasLocalDescendant()) | |
| 267 return true; | |
| 268 } | |
| 269 return false; | |
| 270 } | |
| 271 | |
| 272 void HTMLFrame::LoadRequest(const blink::WebURLRequest& request, | |
| 273 base::TimeTicks navigation_start_time) { | |
| 274 TRACE_EVENT1("html_viewer", "HTMLFrame::LoadRequest", | |
| 275 "url", request.url().string().utf8()); | |
| 276 | |
| 277 DCHECK(IsLocal()); | |
| 278 | |
| 279 DVLOG(2) << "HTMLFrame::LoadRequest this=" << this << " id=" << id_ | |
| 280 << " URL=" << GURL(request.url()); | |
| 281 | |
| 282 pending_navigation_ = false; | |
| 283 navigation_start_time_ = navigation_start_time; | |
| 284 web_frame_->toWebLocalFrame()->loadRequest(request); | |
| 285 } | |
| 286 | |
| 287 HTMLFrame::~HTMLFrame() { | |
| 288 DVLOG(2) << "~HTMLFrame this=" << this << " id=" << id_; | |
| 289 | |
| 290 DCHECK(children_.empty()); | |
| 291 | |
| 292 if (parent_) { | |
| 293 auto iter = | |
| 294 std::find(parent_->children_.begin(), parent_->children_.end(), this); | |
| 295 parent_->children_.erase(iter); | |
| 296 } | |
| 297 parent_ = nullptr; | |
| 298 | |
| 299 frame_tree_manager_->OnFrameDestroyed(this); | |
| 300 | |
| 301 if (delegate_) | |
| 302 delegate_->OnFrameDestroyed(); | |
| 303 | |
| 304 if (window_) { | |
| 305 window_->RemoveObserver(this); | |
| 306 mus::ScopedWindowPtr::DeleteWindowOrWindowManager(window_); | |
| 307 } | |
| 308 } | |
| 309 | |
| 310 blink::WebMediaPlayer* HTMLFrame::createMediaPlayer( | |
| 311 blink::WebLocalFrame* frame, | |
| 312 blink::WebMediaPlayer::LoadType load_type, | |
| 313 const blink::WebURL& url, | |
| 314 blink::WebMediaPlayerClient* client, | |
| 315 blink::WebMediaPlayerEncryptedMediaClient* encrypted_client, | |
| 316 blink::WebContentDecryptionModule* initial_cdm, | |
| 317 const blink::WebString& sink_id, | |
| 318 blink::WebMediaSession* media_session) { | |
| 319 return global_state()->media_factory()->CreateMediaPlayer( | |
| 320 frame, url, client, encrypted_client, initial_cdm, GetShell()); | |
| 321 } | |
| 322 | |
| 323 blink::WebFrame* HTMLFrame::createChildFrame( | |
| 324 blink::WebLocalFrame* parent, | |
| 325 blink::WebTreeScopeType scope, | |
| 326 const blink::WebString& frame_name, | |
| 327 blink::WebSandboxFlags sandbox_flags, | |
| 328 const blink::WebFrameOwnerProperties& frame_owner_properties) { | |
| 329 DCHECK(IsLocal()); // Can't create children of remote frames. | |
| 330 DCHECK_EQ(parent, web_frame_); | |
| 331 DCHECK(window_); // If we're local we have to have a window. | |
| 332 // Create the window that will house the frame now. We embed once we know the | |
| 333 // url (see decidePolicyForNavigation()). | |
| 334 mus::Window* child_window = window_->connection()->NewWindow(); | |
| 335 ReplicatedFrameState child_state; | |
| 336 child_state.name = frame_name; | |
| 337 child_state.tree_scope = scope; | |
| 338 child_state.sandbox_flags = sandbox_flags; | |
| 339 mojo::Map<mojo::String, mojo::Array<uint8_t>> client_properties; | |
| 340 client_properties.mark_non_null(); | |
| 341 ClientPropertiesFromReplicatedFrameState(child_state, &client_properties); | |
| 342 | |
| 343 child_window->SetVisible(true); | |
| 344 window_->AddChild(child_window); | |
| 345 | |
| 346 HTMLFrame::CreateParams params(frame_tree_manager_, this, child_window->id(), | |
| 347 child_window, client_properties, nullptr); | |
| 348 params.is_local_create_child = true; | |
| 349 HTMLFrame* child_frame = GetFirstAncestorWithDelegate() | |
| 350 ->delegate_->GetHTMLFactory() | |
| 351 ->CreateHTMLFrame(¶ms); | |
| 352 child_frame->owned_window_.reset(new mus::ScopedWindowPtr(child_window)); | |
| 353 | |
| 354 web_view::mojom::FrameClientPtr client_ptr; | |
| 355 child_frame->frame_client_binding_.reset( | |
| 356 new mojo::Binding<web_view::mojom::FrameClient>( | |
| 357 child_frame, mojo::GetProxy(&client_ptr))); | |
| 358 server_->OnCreatedFrame(GetProxy(&(child_frame->server_)), | |
| 359 std::move(client_ptr), child_window->id(), | |
| 360 std::move(client_properties)); | |
| 361 return child_frame->web_frame_; | |
| 362 } | |
| 363 | |
| 364 void HTMLFrame::frameDetached(blink::WebFrame* web_frame, | |
| 365 blink::WebFrameClient::DetachType type) { | |
| 366 if (type == blink::WebFrameClient::DetachType::Swap) { | |
| 367 web_frame->close(); | |
| 368 return; | |
| 369 } | |
| 370 | |
| 371 DCHECK(type == blink::WebFrameClient::DetachType::Remove); | |
| 372 FrameDetachedImpl(web_frame); | |
| 373 } | |
| 374 | |
| 375 blink::WebCookieJar* HTMLFrame::cookieJar(blink::WebLocalFrame* frame) { | |
| 376 // TODO(darin): Blink does not fallback to the Platform provided WebCookieJar. | |
| 377 // Either it should, as it once did, or we should find another solution here. | |
| 378 return blink::Platform::current()->cookieJar(); | |
| 379 } | |
| 380 | |
| 381 blink::WebNavigationPolicy HTMLFrame::decidePolicyForNavigation( | |
| 382 const NavigationPolicyInfo& info) { | |
| 383 // If we have extraData() it means we already have the url response | |
| 384 // (presumably because we are being called via Navigate()). In that case we | |
| 385 // can go ahead and navigate locally. | |
| 386 if (info.urlRequest.extraData()) { | |
| 387 DCHECK_EQ(blink::WebNavigationPolicyCurrentTab, info.defaultPolicy); | |
| 388 return blink::WebNavigationPolicyCurrentTab; | |
| 389 } | |
| 390 | |
| 391 // about:blank is treated as the same origin and is always allowed for frames. | |
| 392 if (parent_ && info.urlRequest.url() == GURL(url::kAboutBlankURL) && | |
| 393 info.defaultPolicy == blink::WebNavigationPolicyCurrentTab) { | |
| 394 return blink::WebNavigationPolicyCurrentTab; | |
| 395 } | |
| 396 | |
| 397 // Ask the Frame to handle the navigation. Returning | |
| 398 // WebNavigationPolicyHandledByClient to inform blink that the navigation is | |
| 399 // being handled. | |
| 400 DVLOG(2) << "HTMLFrame::decidePolicyForNavigation calls " | |
| 401 << "Frame::RequestNavigate this=" << this << " id=" << id_ | |
| 402 << " URL=" << GURL(info.urlRequest.url()); | |
| 403 | |
| 404 mojo::URLRequestPtr url_request = mojo::URLRequest::From(info.urlRequest); | |
| 405 url_request->originating_time_ticks = | |
| 406 base::TimeTicks::Now().ToInternalValue(); | |
| 407 server_->RequestNavigate( | |
| 408 WebNavigationPolicyToNavigationTarget(info.defaultPolicy), id_, | |
| 409 std::move(url_request)); | |
| 410 | |
| 411 // TODO(yzshen): crbug.com/532556 If the server side drops the request, | |
| 412 // this frame will be in permenant-loading state. We should send a | |
| 413 // notification to mark this frame as not loading in that case. We also need | |
| 414 // to better keep track of multiple pending navigations. | |
| 415 pending_navigation_ = true; | |
| 416 return blink::WebNavigationPolicyHandledByClient; | |
| 417 } | |
| 418 | |
| 419 bool HTMLFrame::hasPendingNavigation(blink::WebLocalFrame* frame) { | |
| 420 return pending_navigation_; | |
| 421 } | |
| 422 | |
| 423 void HTMLFrame::didHandleOnloadEvents(blink::WebLocalFrame* frame) { | |
| 424 DVLOG(2) << "XXX HTMLFrame::didHandleOnloadEvents id=" << id_; | |
| 425 static bool recorded = false; | |
| 426 if (!recorded && startup_performance_data_collector_) { | |
| 427 startup_performance_data_collector_->SetFirstWebContentsMainFrameLoadTicks( | |
| 428 base::TimeTicks::Now().ToInternalValue()); | |
| 429 recorded = true; | |
| 430 } | |
| 431 } | |
| 432 | |
| 433 void HTMLFrame::didAddMessageToConsole(const blink::WebConsoleMessage& message, | |
| 434 const blink::WebString& source_name, | |
| 435 unsigned source_line, | |
| 436 const blink::WebString& stack_trace) { | |
| 437 VLOG(1) << "[" << source_name.utf8() << "(" << source_line << ")] " | |
| 438 << message.text.utf8(); | |
| 439 } | |
| 440 | |
| 441 void HTMLFrame::didFinishLoad(blink::WebLocalFrame* frame) { | |
| 442 if (GetFirstAncestorWithDelegate() == this) | |
| 443 delegate_->OnFrameDidFinishLoad(); | |
| 444 } | |
| 445 | |
| 446 void HTMLFrame::didNavigateWithinPage(blink::WebLocalFrame* frame, | |
| 447 const blink::WebHistoryItem& history_item, | |
| 448 blink::WebHistoryCommitType commit_type) { | |
| 449 server_->DidNavigateLocally(history_item.urlString().utf8()); | |
| 450 } | |
| 451 | |
| 452 blink::WebGeolocationClient* HTMLFrame::geolocationClient() { | |
| 453 if (!geolocation_client_impl_) | |
| 454 geolocation_client_impl_.reset(new GeolocationClientImpl); | |
| 455 return geolocation_client_impl_.get(); | |
| 456 } | |
| 457 | |
| 458 blink::WebEncryptedMediaClient* HTMLFrame::encryptedMediaClient() { | |
| 459 return global_state()->media_factory()->GetEncryptedMediaClient(); | |
| 460 } | |
| 461 | |
| 462 void HTMLFrame::didStartLoading(bool to_different_document) { | |
| 463 server_->LoadingStateChanged(true, 0.0); | |
| 464 } | |
| 465 | |
| 466 void HTMLFrame::didStopLoading() { | |
| 467 server_->LoadingStateChanged(false, 1.0); | |
| 468 } | |
| 469 | |
| 470 void HTMLFrame::didChangeLoadProgress(double load_progress) { | |
| 471 server_->LoadingStateChanged(true, load_progress); | |
| 472 } | |
| 473 | |
| 474 void HTMLFrame::dispatchLoad() { | |
| 475 // According to comments of WebFrameClient::dispatchLoad(), this should only | |
| 476 // be called when the parent frame is remote. | |
| 477 DCHECK(parent_ && !parent_->IsLocal()); | |
| 478 server_->DispatchLoadEventToParent(); | |
| 479 } | |
| 480 | |
| 481 void HTMLFrame::didChangeName(blink::WebLocalFrame* frame, | |
| 482 const blink::WebString& name) { | |
| 483 state_.name = name; | |
| 484 server_->SetClientProperty(kPropertyFrameName, | |
| 485 FrameNameToClientProperty(name)); | |
| 486 } | |
| 487 | |
| 488 void HTMLFrame::didCommitProvisionalLoad( | |
| 489 blink::WebLocalFrame* frame, | |
| 490 const blink::WebHistoryItem& item, | |
| 491 blink::WebHistoryCommitType commit_type) { | |
| 492 state_.origin = FrameOrigin(frame); | |
| 493 server_->SetClientProperty(kPropertyFrameOrigin, | |
| 494 FrameOriginToClientProperty(frame)); | |
| 495 | |
| 496 // TODO(erg): We need to pass way more information from here through to the | |
| 497 // other side. See FrameHostMsg_DidCommitProvisionalLoad_Params. It is a grab | |
| 498 // bag of everything and it looks like a combination of | |
| 499 // NavigatorImpl::DidNavigate and | |
| 500 // NavigationControllerImpl::RendererDidNavigate use everything passed | |
| 501 // through. | |
| 502 server_->DidCommitProvisionalLoad(); | |
| 503 | |
| 504 if (!navigation_start_time_.is_null()) { | |
| 505 frame->dataSource()->setNavigationStartTime( | |
| 506 navigation_start_time_.ToInternalValue() / | |
| 507 static_cast<double>(base::Time::kMicrosecondsPerSecond)); | |
| 508 navigation_start_time_ = base::TimeTicks(); | |
| 509 } | |
| 510 } | |
| 511 | |
| 512 void HTMLFrame::didReceiveTitle(blink::WebLocalFrame* frame, | |
| 513 const blink::WebString& title, | |
| 514 blink::WebTextDirection direction) { | |
| 515 // TODO(beng): handle |direction|. | |
| 516 mojo::String formatted; | |
| 517 if (!title.isNull()) { | |
| 518 formatted = | |
| 519 mojo::String::From(base::string16(title).substr(0, kMaxTitleChars)); | |
| 520 } | |
| 521 server_->TitleChanged(formatted); | |
| 522 } | |
| 523 | |
| 524 void HTMLFrame::reportFindInFrameMatchCount(int identifier, | |
| 525 int count, | |
| 526 bool finalUpdate) { | |
| 527 server_->OnFindInFrameCountUpdated(identifier, count, finalUpdate); | |
| 528 } | |
| 529 | |
| 530 void HTMLFrame::reportFindInPageSelection(int identifier, | |
| 531 int activeMatchOrdinal, | |
| 532 const blink::WebRect& selection) { | |
| 533 server_->OnFindInPageSelectionUpdated(identifier, activeMatchOrdinal); | |
| 534 } | |
| 535 | |
| 536 bool HTMLFrame::shouldSearchSingleFrame() { | |
| 537 return true; | |
| 538 } | |
| 539 | |
| 540 void HTMLFrame::Bind( | |
| 541 web_view::mojom::FramePtr frame, | |
| 542 mojo::InterfaceRequest<web_view::mojom::FrameClient> frame_client_request) { | |
| 543 DCHECK(IsLocal()); | |
| 544 server_ = std::move(frame); | |
| 545 server_.set_connection_error_handler( | |
| 546 base::Bind(&HTMLFrame::Close, base::Unretained(this))); | |
| 547 frame_client_binding_.reset(new mojo::Binding<web_view::mojom::FrameClient>( | |
| 548 this, std::move(frame_client_request))); | |
| 549 } | |
| 550 | |
| 551 void HTMLFrame::SetValueFromClientProperty(const std::string& name, | |
| 552 mojo::Array<uint8_t> new_data) { | |
| 553 if (IsLocal()) | |
| 554 return; | |
| 555 | |
| 556 // Only the name and origin dynamically change. | |
| 557 if (name == kPropertyFrameOrigin) { | |
| 558 state_.origin = FrameOriginFromClientProperty(new_data); | |
| 559 web_frame_->toWebRemoteFrame()->setReplicatedOrigin(state_.origin); | |
| 560 } else if (name == kPropertyFrameName) { | |
| 561 state_.name = FrameNameFromClientProperty(new_data); | |
| 562 web_frame_->toWebRemoteFrame()->setReplicatedName(state_.name); | |
| 563 } | |
| 564 } | |
| 565 | |
| 566 HTMLFrame* HTMLFrame::GetFirstAncestorWithDelegate() { | |
| 567 HTMLFrame* frame = this; | |
| 568 while (frame && !frame->delegate_) | |
| 569 frame = frame->parent_; | |
| 570 return frame; | |
| 571 } | |
| 572 | |
| 573 mojo::Shell* HTMLFrame::GetShell() { | |
| 574 return GetFirstAncestorWithDelegate()->delegate_->GetShell(); | |
| 575 } | |
| 576 | |
| 577 web_view::mojom::Frame* HTMLFrame::GetServerFrame() { | |
| 578 // Prefer an ancestor with a server Frame. | |
| 579 for (HTMLFrame* frame = this; frame; frame = frame->parent_) { | |
| 580 if (frame->server_.get()) | |
| 581 return frame->server_.get(); | |
| 582 } | |
| 583 | |
| 584 // We're a remote frame with no local frame ancestors. Use the server Frame | |
| 585 // from the local frame of the HTMLFrameTreeManager. | |
| 586 return frame_tree_manager_->local_frame_->server_.get(); | |
| 587 } | |
| 588 | |
| 589 void HTMLFrame::SetWindow(mus::Window* window) { | |
| 590 if (window_) { | |
| 591 window_->set_input_event_handler(nullptr); | |
| 592 window_->RemoveObserver(this); | |
| 593 } | |
| 594 window_ = window; | |
| 595 if (window_) { | |
| 596 window_->AddObserver(this); | |
| 597 window_->set_input_event_handler(this); | |
| 598 } | |
| 599 } | |
| 600 | |
| 601 void HTMLFrame::CreateRootWebWidget() { | |
| 602 DCHECK(!html_widget_); | |
| 603 if (window_) { | |
| 604 HTMLWidgetRootLocal::CreateParams create_params(GetShell(), global_state(), | |
| 605 window_); | |
| 606 html_widget_.reset( | |
| 607 delegate_->GetHTMLFactory()->CreateHTMLWidgetRootLocal(&create_params)); | |
| 608 } else { | |
| 609 html_widget_.reset(new HTMLWidgetRootRemote(global_state())); | |
| 610 } | |
| 611 } | |
| 612 | |
| 613 void HTMLFrame::CreateLocalRootWebWidget(blink::WebLocalFrame* local_frame) { | |
| 614 DCHECK(!html_widget_); | |
| 615 DCHECK(IsLocal()); | |
| 616 html_widget_.reset(new HTMLWidgetLocalRoot(GetShell(), global_state(), | |
| 617 window_, local_frame)); | |
| 618 } | |
| 619 | |
| 620 void HTMLFrame::UpdateFocus() { | |
| 621 blink::WebWidget* web_widget = GetWebWidget(); | |
| 622 if (!web_widget || !window_) | |
| 623 return; | |
| 624 const bool is_focused = window_ && window_->HasFocus(); | |
| 625 web_widget->setFocus(is_focused); | |
| 626 if (web_widget->isWebView()) | |
| 627 static_cast<blink::WebView*>(web_widget)->setIsActive(is_focused); | |
| 628 } | |
| 629 | |
| 630 void HTMLFrame::SwapToRemote() { | |
| 631 TRACE_EVENT0("html_viewer", "HTMLFrame::SwapToRemote"); | |
| 632 | |
| 633 DVLOG(2) << "HTMLFrame::SwapToRemote this=" << this << " id=" << id_; | |
| 634 | |
| 635 DCHECK(IsLocal()); | |
| 636 | |
| 637 HTMLFrameDelegate* delegate = delegate_; | |
| 638 delegate_ = nullptr; | |
| 639 | |
| 640 blink::WebRemoteFrame* remote_frame = | |
| 641 blink::WebRemoteFrame::create(state_.tree_scope, this); | |
| 642 remote_frame->initializeFromFrame(web_frame_->toWebLocalFrame()); | |
| 643 // swap() ends up calling us back and we then close the frame, which deletes | |
| 644 // it. | |
| 645 web_frame_->swap(remote_frame); | |
| 646 if (owned_window_) { | |
| 647 surface_layer_ = | |
| 648 cc::SurfaceLayer::Create(cc_blink::WebLayerImpl::LayerSettings(), | |
| 649 base::Bind(&SatisfyCallback), | |
| 650 base::Bind(&RequireCallback)); | |
| 651 surface_layer_->SetSurfaceId(cc::SurfaceId(owned_window_->window()->id()), | |
| 652 global_state()->device_pixel_ratio(), | |
| 653 owned_window_->window()->bounds().size()); | |
| 654 | |
| 655 web_layer_.reset(new cc_blink::WebLayerImpl(surface_layer_)); | |
| 656 } | |
| 657 remote_frame->setRemoteWebLayer(web_layer_.get()); | |
| 658 remote_frame->setReplicatedName(state_.name); | |
| 659 remote_frame->setReplicatedOrigin(state_.origin); | |
| 660 remote_frame->setReplicatedSandboxFlags(state_.sandbox_flags); | |
| 661 | |
| 662 // Tell the frame that it is actually loading. This prevents its parent | |
| 663 // from prematurely dispatching load event. | |
| 664 remote_frame->didStartLoading(); | |
| 665 pending_navigation_ = false; | |
| 666 | |
| 667 web_frame_ = remote_frame; | |
| 668 SetWindow(nullptr); | |
| 669 server_.reset(); | |
| 670 frame_client_binding_.reset(); | |
| 671 if (delegate) | |
| 672 delegate->OnFrameSwappedToRemote(); | |
| 673 } | |
| 674 | |
| 675 void HTMLFrame::SwapToLocal( | |
| 676 HTMLFrameDelegate* delegate, | |
| 677 mus::Window* window, | |
| 678 const mojo::Map<mojo::String, mojo::Array<uint8_t>>& properties) { | |
| 679 TRACE_EVENT0("html_viewer", "HTMLFrame::SwapToLocal"); | |
| 680 DVLOG(2) << "HTMLFrame::SwapToLocal this=" << this << " id=" << id_; | |
| 681 CHECK(!IsLocal()); | |
| 682 // It doesn't make sense for the root to swap to local. | |
| 683 CHECK(parent_); | |
| 684 delegate_ = delegate; | |
| 685 SetWindow(window); | |
| 686 SetReplicatedFrameStateFromClientProperties(properties, &state_); | |
| 687 blink::WebLocalFrame* local_web_frame = | |
| 688 blink::WebLocalFrame::createProvisional( | |
| 689 this, web_frame_->toWebRemoteFrame(), state_.sandbox_flags, | |
| 690 // TODO(lazyboy): Figure out replicating WebFrameOwnerProperties. | |
| 691 blink::WebFrameOwnerProperties()); | |
| 692 // The swap() ends up calling to frameDetached() and deleting the old. | |
| 693 web_frame_->swap(local_web_frame); | |
| 694 web_frame_ = local_web_frame; | |
| 695 | |
| 696 web_layer_.reset(); | |
| 697 } | |
| 698 | |
| 699 void HTMLFrame::SwapDelegate(HTMLFrameDelegate* delegate) { | |
| 700 DCHECK(IsLocal()); | |
| 701 HTMLFrameDelegate* old_delegate = delegate_; | |
| 702 delegate_ = delegate; | |
| 703 delegate->OnSwap(this, old_delegate); | |
| 704 } | |
| 705 | |
| 706 blink::WebElement HTMLFrame::GetFocusedElement() { | |
| 707 if (!web_view()) | |
| 708 return blink::WebElement(); | |
| 709 | |
| 710 HTMLFrame* frame = this; | |
| 711 while (frame) { | |
| 712 if (frame->web_view()) { | |
| 713 if (frame->web_view()->focusedFrame() == web_frame_) { | |
| 714 blink::WebDocument doc = web_frame_->document(); | |
| 715 if (!doc.isNull()) | |
| 716 return doc.focusedElement(); | |
| 717 } | |
| 718 return blink::WebElement(); | |
| 719 } | |
| 720 frame = frame->parent(); | |
| 721 } | |
| 722 | |
| 723 return blink::WebElement(); | |
| 724 } | |
| 725 | |
| 726 HTMLFrame* HTMLFrame::FindFrameWithWebFrame(blink::WebFrame* web_frame) { | |
| 727 if (web_frame_ == web_frame) | |
| 728 return this; | |
| 729 for (HTMLFrame* child_frame : children_) { | |
| 730 HTMLFrame* result = child_frame->FindFrameWithWebFrame(web_frame); | |
| 731 if (result) | |
| 732 return result; | |
| 733 } | |
| 734 return nullptr; | |
| 735 } | |
| 736 | |
| 737 void HTMLFrame::FrameDetachedImpl(blink::WebFrame* web_frame) { | |
| 738 DCHECK_EQ(web_frame_, web_frame); | |
| 739 | |
| 740 while (!children_.empty()) { | |
| 741 HTMLFrame* child = children_.front(); | |
| 742 child->Close(); | |
| 743 DCHECK(children_.empty() || children_.front() != child); | |
| 744 } | |
| 745 | |
| 746 if (web_frame->parent()) | |
| 747 web_frame->parent()->removeChild(web_frame); | |
| 748 | |
| 749 delete this; | |
| 750 } | |
| 751 | |
| 752 void HTMLFrame::OnWindowBoundsChanged(mus::Window* window, | |
| 753 const gfx::Rect& old_bounds, | |
| 754 const gfx::Rect& new_bounds) { | |
| 755 DCHECK_EQ(window, window_); | |
| 756 if (html_widget_) | |
| 757 html_widget_->OnWindowBoundsChanged(window); | |
| 758 } | |
| 759 | |
| 760 void HTMLFrame::OnWindowDestroyed(mus::Window* window) { | |
| 761 DCHECK_EQ(window, window_); | |
| 762 window_->RemoveObserver(this); | |
| 763 window_ = nullptr; | |
| 764 Close(); | |
| 765 } | |
| 766 | |
| 767 void HTMLFrame::OnWindowFocusChanged(mus::Window* gained_focus, | |
| 768 mus::Window* lost_focus) { | |
| 769 UpdateFocus(); | |
| 770 } | |
| 771 | |
| 772 void HTMLFrame::OnWindowInputEvent(mus::Window* window, | |
| 773 mus::mojom::EventPtr event, | |
| 774 scoped_ptr<base::Closure>* ack_callback) { | |
| 775 if (event->pointer_data && event->pointer_data->location) { | |
| 776 // Blink expects coordintes to be in DIPs. | |
| 777 event->pointer_data->location->x /= global_state()->device_pixel_ratio(); | |
| 778 event->pointer_data->location->y /= global_state()->device_pixel_ratio(); | |
| 779 event->pointer_data->location->screen_x /= | |
| 780 global_state()->device_pixel_ratio(); | |
| 781 event->pointer_data->location->screen_y /= | |
| 782 global_state()->device_pixel_ratio(); | |
| 783 } | |
| 784 | |
| 785 blink::WebWidget* web_widget = GetWebWidget(); | |
| 786 | |
| 787 if (!touch_handler_ && web_widget) | |
| 788 touch_handler_.reset(new TouchHandler(web_widget)); | |
| 789 | |
| 790 if (touch_handler_ && | |
| 791 (event->action == mus::mojom::EventType::POINTER_DOWN || | |
| 792 event->action == mus::mojom::EventType::POINTER_UP || | |
| 793 event->action == mus::mojom::EventType::POINTER_CANCEL || | |
| 794 event->action == mus::mojom::EventType::POINTER_MOVE) && | |
| 795 event->pointer_data && | |
| 796 event->pointer_data->kind == mus::mojom::PointerKind::TOUCH) { | |
| 797 touch_handler_->OnTouchEvent(*event); | |
| 798 return; | |
| 799 } | |
| 800 | |
| 801 if (!web_widget) | |
| 802 return; | |
| 803 | |
| 804 scoped_ptr<blink::WebInputEvent> web_event = | |
| 805 event.To<scoped_ptr<blink::WebInputEvent>>(); | |
| 806 if (web_event) | |
| 807 web_widget->handleInputEvent(*web_event); | |
| 808 } | |
| 809 | |
| 810 void HTMLFrame::OnConnect( | |
| 811 web_view::mojom::FramePtr frame, | |
| 812 uint32_t change_id, | |
| 813 uint32_t window_id, | |
| 814 web_view::mojom::WindowConnectType window_connect_type, | |
| 815 mojo::Array<web_view::mojom::FrameDataPtr> frame_data, | |
| 816 int64_t navigation_start_time_ticks, | |
| 817 const OnConnectCallback& callback) { | |
| 818 // This is called if this frame is created by way of OnCreatedFrame(). | |
| 819 callback.Run(); | |
| 820 } | |
| 821 | |
| 822 void HTMLFrame::OnFrameAdded(uint32_t change_id, | |
| 823 web_view::mojom::FrameDataPtr frame_data) { | |
| 824 frame_tree_manager_->ProcessOnFrameAdded(this, change_id, | |
| 825 std::move(frame_data)); | |
| 826 } | |
| 827 | |
| 828 void HTMLFrame::OnFrameRemoved(uint32_t change_id, uint32_t frame_id) { | |
| 829 frame_tree_manager_->ProcessOnFrameRemoved(this, change_id, frame_id); | |
| 830 } | |
| 831 | |
| 832 void HTMLFrame::OnFrameClientPropertyChanged(uint32_t frame_id, | |
| 833 const mojo::String& name, | |
| 834 mojo::Array<uint8_t> new_value) { | |
| 835 frame_tree_manager_->ProcessOnFrameClientPropertyChanged( | |
| 836 this, frame_id, name, std::move(new_value)); | |
| 837 } | |
| 838 | |
| 839 void HTMLFrame::OnPostMessageEvent(uint32_t source_frame_id, | |
| 840 uint32_t target_frame_id, | |
| 841 HTMLMessageEventPtr serialized_event) { | |
| 842 NOTIMPLEMENTED(); // For message ports. | |
| 843 | |
| 844 HTMLFrame* target = frame_tree_manager_->root_->FindFrame(target_frame_id); | |
| 845 HTMLFrame* source = frame_tree_manager_->root_->FindFrame(source_frame_id); | |
| 846 if (!target || !source) { | |
| 847 DVLOG(1) << "Invalid source or target for PostMessage"; | |
| 848 return; | |
| 849 } | |
| 850 | |
| 851 if (!target->IsLocal()) { | |
| 852 DVLOG(1) << "Target for PostMessage is not lot local"; | |
| 853 return; | |
| 854 } | |
| 855 | |
| 856 blink::WebLocalFrame* target_web_frame = | |
| 857 target->web_frame_->toWebLocalFrame(); | |
| 858 | |
| 859 blink::WebSerializedScriptValue serialized_script_value; | |
| 860 serialized_script_value = blink::WebSerializedScriptValue::fromString( | |
| 861 serialized_event->data.To<blink::WebString>()); | |
| 862 | |
| 863 // We must pass in the target_origin to do the security check on this side, | |
| 864 // since it may have changed since the original postMessage call was made. | |
| 865 blink::WebSecurityOrigin target_origin; | |
| 866 if (!serialized_event->target_origin.is_null()) { | |
| 867 target_origin = blink::WebSecurityOrigin::createFromString( | |
| 868 serialized_event->target_origin.To<blink::WebString>()); | |
| 869 } | |
| 870 | |
| 871 // TODO(esprehn): Shouldn't this also fill in channels like RenderFrameImpl? | |
| 872 blink::WebMessagePortChannelArray channels; | |
| 873 blink::WebDOMMessageEvent msg_event(serialized_script_value, | |
| 874 serialized_event->source_origin.To<blink::WebString>(), | |
| 875 source->web_frame_, target_web_frame->document(), channels); | |
| 876 | |
| 877 target_web_frame->dispatchMessageEventWithOriginCheck(target_origin, | |
| 878 msg_event); | |
| 879 } | |
| 880 | |
| 881 void HTMLFrame::OnWillNavigate(const mojo::String& origin, | |
| 882 const OnWillNavigateCallback& callback) { | |
| 883 bool should_swap = true; | |
| 884 | |
| 885 if (this == frame_tree_manager_->local_frame_) { | |
| 886 HTMLFrame* new_local_frame = frame_tree_manager_->FindNewLocalFrame(); | |
| 887 if (!new_local_frame) { | |
| 888 // All local frames are descendants of |this|. In this case, the whole | |
| 889 // frame tree in the current process is going to be deleted very soon. We | |
| 890 // don't have to swap. | |
| 891 should_swap = false; | |
| 892 } else { | |
| 893 frame_tree_manager_->local_frame_ = new_local_frame; | |
| 894 } | |
| 895 } | |
| 896 | |
| 897 DVLOG(2) << "HTMLFrame::OnWillNavigate this=" << this << " id=" << id_ | |
| 898 << " local=" << IsLocal() << " should_swap=" << should_swap; | |
| 899 callback.Run(); | |
| 900 if (should_swap) { | |
| 901 SwapToRemote(); | |
| 902 const blink::WebSecurityOrigin security_origin( | |
| 903 blink::WebSecurityOrigin::createFromString( | |
| 904 blink::WebString::fromUTF8(origin))); | |
| 905 web_frame_->toWebRemoteFrame()->setReplicatedOrigin(security_origin); | |
| 906 } | |
| 907 } | |
| 908 | |
| 909 void HTMLFrame::OnFrameLoadingStateChanged(uint32_t frame_id, bool loading) { | |
| 910 HTMLFrame* frame = frame_tree_manager_->root_->FindFrame(frame_id); | |
| 911 // TODO(yzshen): (Apply to this method and the one below.) Is it possible that | |
| 912 // at this point the frame is already hosting a different document? | |
| 913 if (frame && !frame->IsLocal()) { | |
| 914 if (loading) | |
| 915 frame->web_frame_->toWebRemoteFrame()->didStartLoading(); | |
| 916 else | |
| 917 frame->web_frame_->toWebRemoteFrame()->didStopLoading(); | |
| 918 } | |
| 919 } | |
| 920 | |
| 921 void HTMLFrame::OnDispatchFrameLoadEvent(uint32_t frame_id) { | |
| 922 HTMLFrame* frame = frame_tree_manager_->root_->FindFrame(frame_id); | |
| 923 if (frame && !frame->IsLocal()) | |
| 924 frame->web_frame_->toWebRemoteFrame()->DispatchLoadEventForFrameOwner(); | |
| 925 } | |
| 926 | |
| 927 void HTMLFrame::Find(int32_t request_id, | |
| 928 const mojo::String& search_text, | |
| 929 web_view::mojom::FindOptionsPtr options, | |
| 930 bool wrap_within_frame, | |
| 931 const FindCallback& callback) { | |
| 932 blink::WebRect selection_rect; | |
| 933 bool result = web_frame_->toWebLocalFrame()->find( | |
| 934 request_id, search_text.To<blink::WebString>(), | |
| 935 options.To<blink::WebFindOptions>(), wrap_within_frame, &selection_rect); | |
| 936 | |
| 937 if (!result) { | |
| 938 // don't leave text selected as you move to the next frame. | |
| 939 web_frame_->executeCommand(blink::WebString::fromUTF8("Unselect"), | |
| 940 GetFocusedElement()); | |
| 941 } | |
| 942 | |
| 943 callback.Run(result); | |
| 944 } | |
| 945 | |
| 946 void HTMLFrame::StopFinding(bool clear_selection) { | |
| 947 // TODO(erg): |clear_selection| isn't correct; this should be a state enum | |
| 948 // that lets us STOP_FIND_ACTION_ACTIVATE_SELECTION, too. | |
| 949 if (clear_selection) { | |
| 950 blink::WebElement focused_element = GetFocusedElement(); | |
| 951 if (!focused_element.isNull()) { | |
| 952 web_frame_->executeCommand(blink::WebString::fromUTF8("Unselect"), | |
| 953 focused_element); | |
| 954 } | |
| 955 } | |
| 956 | |
| 957 web_frame_->toWebLocalFrame()->stopFinding(clear_selection); | |
| 958 } | |
| 959 | |
| 960 void HTMLFrame::HighlightFindResults(int32_t request_id, | |
| 961 const mojo::String& search_text, | |
| 962 web_view::mojom::FindOptionsPtr options, | |
| 963 bool reset) { | |
| 964 web_frame_->toWebLocalFrame()->scopeStringMatches( | |
| 965 request_id, search_text.To<blink::WebString>(), | |
| 966 options.To<blink::WebFindOptions>(), reset); | |
| 967 } | |
| 968 | |
| 969 void HTMLFrame::StopHighlightingFindResults() { | |
| 970 web_frame_->toWebLocalFrame()->resetMatchCount(); | |
| 971 web_frame_->toWebLocalFrame()->cancelPendingScopingEffort(); | |
| 972 } | |
| 973 | |
| 974 void HTMLFrame::frameDetached(blink::WebRemoteFrameClient::DetachType type) { | |
| 975 if (type == blink::WebRemoteFrameClient::DetachType::Swap) { | |
| 976 web_frame_->close(); | |
| 977 return; | |
| 978 } | |
| 979 | |
| 980 DCHECK(type == blink::WebRemoteFrameClient::DetachType::Remove); | |
| 981 FrameDetachedImpl(web_frame_); | |
| 982 } | |
| 983 | |
| 984 void HTMLFrame::postMessageEvent(blink::WebLocalFrame* source_web_frame, | |
| 985 blink::WebRemoteFrame* target_web_frame, | |
| 986 blink::WebSecurityOrigin target_origin, | |
| 987 blink::WebDOMMessageEvent web_event) { | |
| 988 NOTIMPLEMENTED(); // message_ports aren't implemented yet. | |
| 989 | |
| 990 HTMLFrame* source_frame = | |
| 991 frame_tree_manager_->root_->FindFrameWithWebFrame(source_web_frame); | |
| 992 DCHECK(source_frame); | |
| 993 HTMLFrame* target_frame = | |
| 994 frame_tree_manager_->root_->FindFrameWithWebFrame(target_web_frame); | |
| 995 DCHECK(target_frame); | |
| 996 | |
| 997 HTMLMessageEventPtr event(HTMLMessageEvent::New()); | |
| 998 event->data = mojo::Array<uint8_t>::From(web_event.data().toString()); | |
| 999 event->source_origin = mojo::String::From(web_event.origin()); | |
| 1000 if (!target_origin.isNull()) | |
| 1001 event->target_origin = mojo::String::From(target_origin.toString()); | |
| 1002 | |
| 1003 source_frame->server_->PostMessageEventToFrame(target_frame->id_, | |
| 1004 std::move(event)); | |
| 1005 } | |
| 1006 | |
| 1007 void HTMLFrame::initializeChildFrame(const blink::WebRect& frame_rect, | |
| 1008 float scale_factor) { | |
| 1009 // NOTE: |scale_factor| is always 1. | |
| 1010 const gfx::Rect rect_in_dip(frame_rect.x, frame_rect.y, frame_rect.width, | |
| 1011 frame_rect.height); | |
| 1012 const gfx::Rect rect_in_pixels(gfx::ConvertRectToPixel( | |
| 1013 global_state()->device_pixel_ratio(), rect_in_dip)); | |
| 1014 window_->SetBounds(rect_in_pixels); | |
| 1015 } | |
| 1016 | |
| 1017 void HTMLFrame::navigate(const blink::WebURLRequest& request, | |
| 1018 bool should_replace_current_entry) { | |
| 1019 // TODO: support |should_replace_current_entry|. | |
| 1020 NOTIMPLEMENTED(); // for |should_replace_current_entry | |
| 1021 mojo::URLRequestPtr url_request = mojo::URLRequest::From(request); | |
| 1022 GetServerFrame()->RequestNavigate( | |
| 1023 web_view::mojom::NavigationTargetType::EXISTING_FRAME, id_, | |
| 1024 std::move(url_request)); | |
| 1025 } | |
| 1026 | |
| 1027 void HTMLFrame::reload(bool ignore_cache, bool is_client_redirect) { | |
| 1028 NOTIMPLEMENTED(); | |
| 1029 } | |
| 1030 | |
| 1031 void HTMLFrame::frameRectsChanged(const blink::WebRect& frame_rect) { | |
| 1032 // Only the owner of window can update its size. | |
| 1033 if (!owned_window_) | |
| 1034 return; | |
| 1035 | |
| 1036 const gfx::Rect rect_in_dip(frame_rect.x, frame_rect.y, frame_rect.width, | |
| 1037 frame_rect.height); | |
| 1038 const gfx::Rect rect_in_pixels(gfx::ConvertRectToPixel( | |
| 1039 global_state()->device_pixel_ratio(), rect_in_dip)); | |
| 1040 owned_window_->window()->SetBounds(rect_in_pixels); | |
| 1041 | |
| 1042 if (!surface_layer_) | |
| 1043 return; | |
| 1044 | |
| 1045 surface_layer_->SetSurfaceId(cc::SurfaceId(owned_window_->window()->id()), | |
| 1046 global_state()->device_pixel_ratio(), | |
| 1047 owned_window_->window()->bounds().size()); | |
| 1048 } | |
| 1049 | |
| 1050 } // namespace mojo | |
| OLD | NEW |