OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/render_frame_impl.h" | 5 #include "content/renderer/render_frame_impl.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/debug/alias.h" | 11 #include "base/debug/alias.h" |
12 #include "base/debug/dump_without_crashing.h" | 12 #include "base/debug/dump_without_crashing.h" |
13 #include "base/i18n/char_iterator.h" | 13 #include "base/i18n/char_iterator.h" |
| 14 #include "base/metrics/histogram.h" |
14 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
15 #include "base/time/time.h" | 16 #include "base/time/time.h" |
16 #include "content/child/appcache/appcache_dispatcher.h" | 17 #include "content/child/appcache/appcache_dispatcher.h" |
17 #include "content/child/plugin_messages.h" | 18 #include "content/child/plugin_messages.h" |
18 #include "content/child/quota_dispatcher.h" | 19 #include "content/child/quota_dispatcher.h" |
19 #include "content/child/request_extra_data.h" | 20 #include "content/child/request_extra_data.h" |
20 #include "content/child/service_worker/web_service_worker_provider_impl.h" | 21 #include "content/child/service_worker/web_service_worker_provider_impl.h" |
21 #include "content/common/frame_messages.h" | 22 #include "content/common/frame_messages.h" |
22 #include "content/common/socket_stream_handle_data.h" | 23 #include "content/common/socket_stream_handle_data.h" |
23 #include "content/common/swapped_out_messages.h" | 24 #include "content/common/swapped_out_messages.h" |
24 #include "content/common/view_messages.h" | 25 #include "content/common/view_messages.h" |
25 #include "content/public/common/content_constants.h" | 26 #include "content/public/common/content_constants.h" |
26 #include "content/public/common/content_switches.h" | 27 #include "content/public/common/content_switches.h" |
27 #include "content/public/common/context_menu_params.h" | 28 #include "content/public/common/context_menu_params.h" |
28 #include "content/public/common/url_constants.h" | 29 #include "content/public/common/url_constants.h" |
29 #include "content/public/common/url_utils.h" | 30 #include "content/public/common/url_utils.h" |
30 #include "content/public/renderer/content_renderer_client.h" | 31 #include "content/public/renderer/content_renderer_client.h" |
31 #include "content/public/renderer/context_menu_client.h" | 32 #include "content/public/renderer/context_menu_client.h" |
32 #include "content/public/renderer/document_state.h" | 33 #include "content/public/renderer/document_state.h" |
| 34 #include "content/public/renderer/history_item_serialization.h" |
33 #include "content/public/renderer/navigation_state.h" | 35 #include "content/public/renderer/navigation_state.h" |
34 #include "content/public/renderer/render_frame_observer.h" | 36 #include "content/public/renderer/render_frame_observer.h" |
35 #include "content/renderer/accessibility/renderer_accessibility.h" | 37 #include "content/renderer/accessibility/renderer_accessibility.h" |
36 #include "content/renderer/browser_plugin/browser_plugin.h" | 38 #include "content/renderer/browser_plugin/browser_plugin.h" |
37 #include "content/renderer/browser_plugin/browser_plugin_manager.h" | 39 #include "content/renderer/browser_plugin/browser_plugin_manager.h" |
38 #include "content/renderer/child_frame_compositing_helper.h" | 40 #include "content/renderer/child_frame_compositing_helper.h" |
39 #include "content/renderer/context_menu_params_builder.h" | 41 #include "content/renderer/context_menu_params_builder.h" |
40 #include "content/renderer/internal_document_state_data.h" | 42 #include "content/renderer/internal_document_state_data.h" |
41 #include "content/renderer/npapi/plugin_channel_host.h" | 43 #include "content/renderer/npapi/plugin_channel_host.h" |
42 #include "content/renderer/render_thread_impl.h" | 44 #include "content/renderer/render_thread_impl.h" |
43 #include "content/renderer/render_view_impl.h" | 45 #include "content/renderer/render_view_impl.h" |
44 #include "content/renderer/render_widget_fullscreen_pepper.h" | 46 #include "content/renderer/render_widget_fullscreen_pepper.h" |
45 #include "content/renderer/renderer_webapplicationcachehost_impl.h" | 47 #include "content/renderer/renderer_webapplicationcachehost_impl.h" |
46 #include "content/renderer/shared_worker_repository.h" | 48 #include "content/renderer/shared_worker_repository.h" |
47 #include "content/renderer/websharedworker_proxy.h" | 49 #include "content/renderer/websharedworker_proxy.h" |
48 #include "net/base/net_errors.h" | 50 #include "net/base/net_errors.h" |
49 #include "net/http/http_util.h" | 51 #include "net/http/http_util.h" |
50 #include "third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h" | 52 #include "third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h" |
51 #include "third_party/WebKit/public/platform/WebString.h" | 53 #include "third_party/WebKit/public/platform/WebString.h" |
52 #include "third_party/WebKit/public/platform/WebURL.h" | 54 #include "third_party/WebKit/public/platform/WebURL.h" |
53 #include "third_party/WebKit/public/platform/WebURLError.h" | 55 #include "third_party/WebKit/public/platform/WebURLError.h" |
54 #include "third_party/WebKit/public/platform/WebURLResponse.h" | 56 #include "third_party/WebKit/public/platform/WebURLResponse.h" |
55 #include "third_party/WebKit/public/platform/WebVector.h" | 57 #include "third_party/WebKit/public/platform/WebVector.h" |
56 #include "third_party/WebKit/public/web/WebDocument.h" | 58 #include "third_party/WebKit/public/web/WebDocument.h" |
57 #include "third_party/WebKit/public/web/WebFrame.h" | 59 #include "third_party/WebKit/public/web/WebFrame.h" |
| 60 #include "third_party/WebKit/public/web/WebGlyphCache.h" |
58 #include "third_party/WebKit/public/web/WebNavigationPolicy.h" | 61 #include "third_party/WebKit/public/web/WebNavigationPolicy.h" |
59 #include "third_party/WebKit/public/web/WebPlugin.h" | 62 #include "third_party/WebKit/public/web/WebPlugin.h" |
60 #include "third_party/WebKit/public/web/WebPluginParams.h" | 63 #include "third_party/WebKit/public/web/WebPluginParams.h" |
61 #include "third_party/WebKit/public/web/WebSearchableFormData.h" | 64 #include "third_party/WebKit/public/web/WebSearchableFormData.h" |
62 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" | 65 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" |
63 #include "third_party/WebKit/public/web/WebSecurityPolicy.h" | 66 #include "third_party/WebKit/public/web/WebSecurityPolicy.h" |
64 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" | 67 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" |
65 #include "third_party/WebKit/public/web/WebView.h" | 68 #include "third_party/WebKit/public/web/WebView.h" |
66 #include "webkit/child/weburlresponse_extradata_impl.h" | 69 #include "webkit/child/weburlresponse_extradata_impl.h" |
67 | 70 |
68 #if defined(ENABLE_PLUGINS) | 71 #if defined(ENABLE_PLUGINS) |
69 #include "content/renderer/npapi/webplugin_impl.h" | 72 #include "content/renderer/npapi/webplugin_impl.h" |
70 #include "content/renderer/pepper/pepper_browser_connection.h" | 73 #include "content/renderer/pepper/pepper_browser_connection.h" |
71 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" | 74 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" |
72 #include "content/renderer/pepper/pepper_webplugin_impl.h" | 75 #include "content/renderer/pepper/pepper_webplugin_impl.h" |
73 #include "content/renderer/pepper/plugin_module.h" | 76 #include "content/renderer/pepper/plugin_module.h" |
74 #endif | 77 #endif |
75 | 78 |
76 #if defined(ENABLE_WEBRTC) | 79 #if defined(ENABLE_WEBRTC) |
77 #include "content/renderer/media/rtc_peer_connection_handler.h" | 80 #include "content/renderer/media/rtc_peer_connection_handler.h" |
78 #endif | 81 #endif |
79 | 82 |
80 using blink::WebContextMenuData; | 83 using blink::WebContextMenuData; |
81 using blink::WebDataSource; | 84 using blink::WebDataSource; |
82 using blink::WebDocument; | 85 using blink::WebDocument; |
83 using blink::WebFrame; | 86 using blink::WebFrame; |
| 87 using blink::WebHistoryItem; |
84 using blink::WebNavigationPolicy; | 88 using blink::WebNavigationPolicy; |
85 using blink::WebPluginParams; | 89 using blink::WebPluginParams; |
86 using blink::WebReferrerPolicy; | 90 using blink::WebReferrerPolicy; |
87 using blink::WebSearchableFormData; | 91 using blink::WebSearchableFormData; |
88 using blink::WebSecurityOrigin; | 92 using blink::WebSecurityOrigin; |
89 using blink::WebSecurityPolicy; | 93 using blink::WebSecurityPolicy; |
90 using blink::WebServiceWorkerProvider; | 94 using blink::WebServiceWorkerProvider; |
91 using blink::WebStorageQuotaCallbacks; | 95 using blink::WebStorageQuotaCallbacks; |
92 using blink::WebString; | 96 using blink::WebString; |
93 using blink::WebURL; | 97 using blink::WebURL; |
94 using blink::WebURLError; | 98 using blink::WebURLError; |
95 using blink::WebURLRequest; | 99 using blink::WebURLRequest; |
96 using blink::WebURLResponse; | 100 using blink::WebURLResponse; |
97 using blink::WebUserGestureIndicator; | 101 using blink::WebUserGestureIndicator; |
98 using blink::WebVector; | 102 using blink::WebVector; |
99 using blink::WebView; | 103 using blink::WebView; |
100 using base::Time; | 104 using base::Time; |
101 using base::TimeDelta; | 105 using base::TimeDelta; |
102 using webkit_glue::WebURLResponseExtraDataImpl; | 106 using webkit_glue::WebURLResponseExtraDataImpl; |
103 | 107 |
104 namespace content { | 108 namespace content { |
105 | 109 |
106 namespace { | 110 namespace { |
107 | 111 |
108 typedef std::map<blink::WebFrame*, RenderFrameImpl*> FrameMap; | 112 typedef std::map<blink::WebFrame*, RenderFrameImpl*> FrameMap; |
109 base::LazyInstance<FrameMap> g_frame_map = LAZY_INSTANCE_INITIALIZER; | 113 base::LazyInstance<FrameMap> g_frame_map = LAZY_INSTANCE_INITIALIZER; |
110 | 114 |
| 115 int64 ExtractPostId(const WebHistoryItem& item) { |
| 116 if (item.isNull()) |
| 117 return -1; |
| 118 |
| 119 if (item.httpBody().isNull()) |
| 120 return -1; |
| 121 |
| 122 return item.httpBody().identifier(); |
| 123 } |
| 124 |
| 125 WebURLResponseExtraDataImpl* GetExtraDataFromResponse( |
| 126 const WebURLResponse& response) { |
| 127 return static_cast<WebURLResponseExtraDataImpl*>( |
| 128 response.extraData()); |
| 129 } |
| 130 |
| 131 void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) { |
| 132 // Replace any occurrences of swappedout:// with about:blank. |
| 133 const WebURL& blank_url = GURL(kAboutBlankURL); |
| 134 WebVector<WebURL> urls; |
| 135 ds->redirectChain(urls); |
| 136 result->reserve(urls.size()); |
| 137 for (size_t i = 0; i < urls.size(); ++i) { |
| 138 if (urls[i] != GURL(kSwappedOutURL)) |
| 139 result->push_back(urls[i]); |
| 140 else |
| 141 result->push_back(blank_url); |
| 142 } |
| 143 } |
| 144 |
111 } // namespace | 145 } // namespace |
112 | 146 |
113 static RenderFrameImpl* (*g_create_render_frame_impl)(RenderViewImpl*, int32) = | 147 static RenderFrameImpl* (*g_create_render_frame_impl)(RenderViewImpl*, int32) = |
114 NULL; | 148 NULL; |
115 | 149 |
116 // static | 150 // static |
117 RenderFrameImpl* RenderFrameImpl::Create(RenderViewImpl* render_view, | 151 RenderFrameImpl* RenderFrameImpl::Create(RenderViewImpl* render_view, |
118 int32 routing_id) { | 152 int32 routing_id) { |
119 DCHECK(routing_id != MSG_ROUTING_NONE); | 153 DCHECK(routing_id != MSG_ROUTING_NONE); |
120 | 154 |
(...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 if (frame->parent()) | 982 if (frame->parent()) |
949 return; | 983 return; |
950 // Received a redirect on the main frame. | 984 // Received a redirect on the main frame. |
951 WebDataSource* data_source = frame->provisionalDataSource(); | 985 WebDataSource* data_source = frame->provisionalDataSource(); |
952 if (!data_source) { | 986 if (!data_source) { |
953 // Should only be invoked when we have a data source. | 987 // Should only be invoked when we have a data source. |
954 NOTREACHED(); | 988 NOTREACHED(); |
955 return; | 989 return; |
956 } | 990 } |
957 std::vector<GURL> redirects; | 991 std::vector<GURL> redirects; |
958 RenderViewImpl::GetRedirectChain(data_source, &redirects); | 992 GetRedirectChain(data_source, &redirects); |
959 if (redirects.size() >= 2) { | 993 if (redirects.size() >= 2) { |
960 Send(new FrameHostMsg_DidRedirectProvisionalLoad( | 994 Send(new FrameHostMsg_DidRedirectProvisionalLoad( |
961 routing_id_, | 995 routing_id_, |
962 render_view_->page_id_, | 996 render_view_->page_id_, |
963 redirects[redirects.size() - 2], | 997 redirects[redirects.size() - 2], |
964 redirects.back())); | 998 redirects.back())); |
965 } | 999 } |
966 } | 1000 } |
967 | 1001 |
968 void RenderFrameImpl::didFailProvisionalLoad( | 1002 void RenderFrameImpl::didFailProvisionalLoad( |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1061 replace; | 1095 replace; |
1062 } | 1096 } |
1063 | 1097 |
1064 // Load an error page. | 1098 // Load an error page. |
1065 render_view_->LoadNavigationErrorPage( | 1099 render_view_->LoadNavigationErrorPage( |
1066 frame, failed_request, error, replace); | 1100 frame, failed_request, error, replace); |
1067 } | 1101 } |
1068 | 1102 |
1069 void RenderFrameImpl::didCommitProvisionalLoad(blink::WebFrame* frame, | 1103 void RenderFrameImpl::didCommitProvisionalLoad(blink::WebFrame* frame, |
1070 bool is_new_navigation) { | 1104 bool is_new_navigation) { |
1071 // TODO(nasko): Move implementation here. Needed state: | 1105 DocumentState* document_state = |
1072 // * page_id_ | 1106 DocumentState::FromDataSource(frame->dataSource()); |
1073 // * next_page_id_ | 1107 NavigationState* navigation_state = document_state->navigation_state(); |
1074 // * history_list_offset_ | 1108 InternalDocumentStateData* internal_data = |
1075 // * history_list_length_ | 1109 InternalDocumentStateData::FromDocumentState(document_state); |
1076 // * history_page_ids_ | 1110 |
1077 // Needed methods | 1111 if (document_state->commit_load_time().is_null()) |
1078 // * webview | 1112 document_state->set_commit_load_time(Time::Now()); |
1079 // * UpdateSessionHistory | 1113 |
1080 // * GetLoadingUrl | 1114 if (internal_data->must_reset_scroll_and_scale_state()) { |
| 1115 render_view_->webview()->resetScrollAndScaleState(); |
| 1116 internal_data->set_must_reset_scroll_and_scale_state(false); |
| 1117 } |
| 1118 internal_data->set_use_error_page(false); |
| 1119 |
| 1120 if (is_new_navigation) { |
| 1121 // When we perform a new navigation, we need to update the last committed |
| 1122 // session history entry with state for the page we are leaving. |
| 1123 render_view_->UpdateSessionHistory(frame); |
| 1124 |
| 1125 // We bump our Page ID to correspond with the new session history entry. |
| 1126 render_view_->page_id_ = render_view_->next_page_id_++; |
| 1127 |
| 1128 // Don't update history_page_ids_ (etc) for kSwappedOutURL, since |
| 1129 // we don't want to forget the entry that was there, and since we will |
| 1130 // never come back to kSwappedOutURL. Note that we have to call |
| 1131 // UpdateSessionHistory and update page_id_ even in this case, so that |
| 1132 // the current entry gets a state update and so that we don't send a |
| 1133 // state update to the wrong entry when we swap back in. |
| 1134 if (render_view_->GetLoadingUrl(frame) != GURL(kSwappedOutURL)) { |
| 1135 // Advance our offset in session history, applying the length limit. |
| 1136 // There is now no forward history. |
| 1137 render_view_->history_list_offset_++; |
| 1138 if (render_view_->history_list_offset_ >= kMaxSessionHistoryEntries) |
| 1139 render_view_->history_list_offset_ = kMaxSessionHistoryEntries - 1; |
| 1140 render_view_->history_list_length_ = |
| 1141 render_view_->history_list_offset_ + 1; |
| 1142 render_view_->history_page_ids_.resize( |
| 1143 render_view_->history_list_length_, -1); |
| 1144 render_view_->history_page_ids_[render_view_->history_list_offset_] = |
| 1145 render_view_->page_id_; |
| 1146 } |
| 1147 } else { |
| 1148 // Inspect the navigation_state on this frame to see if the navigation |
| 1149 // corresponds to a session history navigation... Note: |frame| may or |
| 1150 // may not be the toplevel frame, but for the case of capturing session |
| 1151 // history, the first committed frame suffices. We keep track of whether |
| 1152 // we've seen this commit before so that only capture session history once |
| 1153 // per navigation. |
| 1154 // |
| 1155 // Note that we need to check if the page ID changed. In the case of a |
| 1156 // reload, the page ID doesn't change, and UpdateSessionHistory gets the |
| 1157 // previous URL and the current page ID, which would be wrong. |
| 1158 if (navigation_state->pending_page_id() != -1 && |
| 1159 navigation_state->pending_page_id() != render_view_->page_id_ && |
| 1160 !navigation_state->request_committed()) { |
| 1161 // This is a successful session history navigation! |
| 1162 render_view_->UpdateSessionHistory(frame); |
| 1163 render_view_->page_id_ = navigation_state->pending_page_id(); |
| 1164 |
| 1165 render_view_->history_list_offset_ = |
| 1166 navigation_state->pending_history_list_offset(); |
| 1167 |
| 1168 // If the history list is valid, our list of page IDs should be correct. |
| 1169 DCHECK(render_view_->history_list_length_ <= 0 || |
| 1170 render_view_->history_list_offset_ < 0 || |
| 1171 render_view_->history_list_offset_ >= |
| 1172 render_view_->history_list_length_ || |
| 1173 render_view_->history_page_ids_[render_view_->history_list_offset_] |
| 1174 == render_view_->page_id_); |
| 1175 } |
| 1176 } |
| 1177 |
1081 render_view_->didCommitProvisionalLoad(frame, is_new_navigation); | 1178 render_view_->didCommitProvisionalLoad(frame, is_new_navigation); |
1082 | |
1083 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, | 1179 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, |
1084 DidCommitProvisionalLoad(is_new_navigation)); | 1180 DidCommitProvisionalLoad(is_new_navigation)); |
| 1181 |
| 1182 // Remember that we've already processed this request, so we don't update |
| 1183 // the session history again. We do this regardless of whether this is |
| 1184 // a session history navigation, because if we attempted a session history |
| 1185 // navigation without valid HistoryItem state, WebCore will think it is a |
| 1186 // new navigation. |
| 1187 navigation_state->set_request_committed(true); |
| 1188 |
| 1189 UpdateURL(frame); |
| 1190 |
| 1191 // Check whether we have new encoding name. |
| 1192 render_view_->UpdateEncoding(frame, frame->view()->pageEncoding().utf8()); |
1085 } | 1193 } |
1086 | 1194 |
1087 void RenderFrameImpl::didClearWindowObject(blink::WebFrame* frame, | 1195 void RenderFrameImpl::didClearWindowObject(blink::WebFrame* frame, |
1088 int world_id) { | 1196 int world_id) { |
1089 // TODO(nasko): Move implementation here. Needed state: | 1197 // TODO(nasko): Move implementation here. Needed state: |
1090 // * enabled_bindings_ | 1198 // * enabled_bindings_ |
1091 // * dom_automation_controller_ | 1199 // * dom_automation_controller_ |
1092 // * stats_collection_controller_ | 1200 // * stats_collection_controller_ |
1093 render_view_->didClearWindowObject(frame, world_id); | 1201 render_view_->didClearWindowObject(frame, world_id); |
1094 } | 1202 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1144 void RenderFrameImpl::didFinishLoad(blink::WebFrame* frame) { | 1252 void RenderFrameImpl::didFinishLoad(blink::WebFrame* frame) { |
1145 // TODO(nasko): Move implementation here. No state needed, just observers | 1253 // TODO(nasko): Move implementation here. No state needed, just observers |
1146 // notification before sending message to the browser process. | 1254 // notification before sending message to the browser process. |
1147 render_view_->didFinishLoad(frame); | 1255 render_view_->didFinishLoad(frame); |
1148 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, | 1256 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, |
1149 DidFinishLoad()); | 1257 DidFinishLoad()); |
1150 } | 1258 } |
1151 | 1259 |
1152 void RenderFrameImpl::didNavigateWithinPage(blink::WebFrame* frame, | 1260 void RenderFrameImpl::didNavigateWithinPage(blink::WebFrame* frame, |
1153 bool is_new_navigation) { | 1261 bool is_new_navigation) { |
1154 // TODO(nasko): Move implementation here. No state needed, just observers | 1262 // If this was a reference fragment navigation that we initiated, then we |
1155 // notification before sending message to the browser process. | 1263 // could end up having a non-null pending navigation params. We just need to |
1156 render_view_->didNavigateWithinPage(frame, is_new_navigation); | 1264 // update the ExtraData on the datasource so that others who read the |
| 1265 // ExtraData will get the new NavigationState. Similarly, if we did not |
| 1266 // initiate this navigation, then we need to take care to reset any pre- |
| 1267 // existing navigation state to a content-initiated navigation state. |
| 1268 // DidCreateDataSource conveniently takes care of this for us. |
| 1269 didCreateDataSource(frame, frame->dataSource()); |
| 1270 |
| 1271 DocumentState* document_state = |
| 1272 DocumentState::FromDataSource(frame->dataSource()); |
| 1273 NavigationState* new_state = document_state->navigation_state(); |
| 1274 new_state->set_was_within_same_page(true); |
| 1275 |
| 1276 didCommitProvisionalLoad(frame, is_new_navigation); |
1157 } | 1277 } |
1158 | 1278 |
1159 void RenderFrameImpl::didUpdateCurrentHistoryItem(blink::WebFrame* frame) { | 1279 void RenderFrameImpl::didUpdateCurrentHistoryItem(blink::WebFrame* frame) { |
1160 // TODO(nasko): Move implementation here. Needed methods: | 1280 // TODO(nasko): Move implementation here. Needed methods: |
1161 // * StartNavStateSyncTimerIfNecessary | 1281 // * StartNavStateSyncTimerIfNecessary |
1162 render_view_->didUpdateCurrentHistoryItem(frame); | 1282 render_view_->didUpdateCurrentHistoryItem(frame); |
1163 } | 1283 } |
1164 | 1284 |
1165 void RenderFrameImpl::willRequestAfterPreconnect( | 1285 void RenderFrameImpl::willRequestAfterPreconnect( |
1166 blink::WebFrame* frame, | 1286 blink::WebFrame* frame, |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1323 // If we are in view source mode, then just let the user see the source of | 1443 // If we are in view source mode, then just let the user see the source of |
1324 // the server's error page. | 1444 // the server's error page. |
1325 if (frame->isViewSourceModeEnabled()) | 1445 if (frame->isViewSourceModeEnabled()) |
1326 return; | 1446 return; |
1327 | 1447 |
1328 DocumentState* document_state = | 1448 DocumentState* document_state = |
1329 DocumentState::FromDataSource(frame->provisionalDataSource()); | 1449 DocumentState::FromDataSource(frame->provisionalDataSource()); |
1330 int http_status_code = response.httpStatusCode(); | 1450 int http_status_code = response.httpStatusCode(); |
1331 | 1451 |
1332 // Record page load flags. | 1452 // Record page load flags. |
1333 WebURLResponseExtraDataImpl* extra_data = | 1453 WebURLResponseExtraDataImpl* extra_data = GetExtraDataFromResponse(response); |
1334 RenderViewImpl::GetExtraDataFromResponse(response); | |
1335 if (extra_data) { | 1454 if (extra_data) { |
1336 document_state->set_was_fetched_via_spdy( | 1455 document_state->set_was_fetched_via_spdy( |
1337 extra_data->was_fetched_via_spdy()); | 1456 extra_data->was_fetched_via_spdy()); |
1338 document_state->set_was_npn_negotiated( | 1457 document_state->set_was_npn_negotiated( |
1339 extra_data->was_npn_negotiated()); | 1458 extra_data->was_npn_negotiated()); |
1340 document_state->set_npn_negotiated_protocol( | 1459 document_state->set_npn_negotiated_protocol( |
1341 extra_data->npn_negotiated_protocol()); | 1460 extra_data->npn_negotiated_protocol()); |
1342 document_state->set_was_alternate_protocol_available( | 1461 document_state->set_was_alternate_protocol_available( |
1343 extra_data->was_alternate_protocol_available()); | 1462 extra_data->was_alternate_protocol_available()); |
1344 document_state->set_connection_info( | 1463 document_state->set_connection_info( |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1635 | 1754 |
1636 void RenderFrameImpl::RemoveObserver(RenderFrameObserver* observer) { | 1755 void RenderFrameImpl::RemoveObserver(RenderFrameObserver* observer) { |
1637 observer->RenderFrameGone(); | 1756 observer->RenderFrameGone(); |
1638 observers_.RemoveObserver(observer); | 1757 observers_.RemoveObserver(observer); |
1639 } | 1758 } |
1640 | 1759 |
1641 void RenderFrameImpl::OnStop() { | 1760 void RenderFrameImpl::OnStop() { |
1642 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, OnStop()); | 1761 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, OnStop()); |
1643 } | 1762 } |
1644 | 1763 |
| 1764 // Tell the embedding application that the URL of the active page has changed. |
| 1765 void RenderFrameImpl::UpdateURL(WebFrame* frame) { |
| 1766 WebDataSource* ds = frame->dataSource(); |
| 1767 DCHECK(ds); |
| 1768 |
| 1769 const WebURLRequest& request = ds->request(); |
| 1770 const WebURLRequest& original_request = ds->originalRequest(); |
| 1771 const WebURLResponse& response = ds->response(); |
| 1772 |
| 1773 DocumentState* document_state = DocumentState::FromDataSource(ds); |
| 1774 NavigationState* navigation_state = document_state->navigation_state(); |
| 1775 InternalDocumentStateData* internal_data = |
| 1776 InternalDocumentStateData::FromDocumentState(document_state); |
| 1777 |
| 1778 FrameHostMsg_DidCommitProvisionalLoad_Params params; |
| 1779 params.http_status_code = response.httpStatusCode(); |
| 1780 params.is_post = false; |
| 1781 params.post_id = -1; |
| 1782 params.page_id = render_view_->page_id_; |
| 1783 params.frame_id = frame->identifier(); |
| 1784 params.frame_unique_name = frame->uniqueName(); |
| 1785 params.socket_address.set_host(response.remoteIPAddress().utf8()); |
| 1786 params.socket_address.set_port(response.remotePort()); |
| 1787 WebURLResponseExtraDataImpl* extra_data = GetExtraDataFromResponse(response); |
| 1788 if (extra_data) |
| 1789 params.was_fetched_via_proxy = extra_data->was_fetched_via_proxy(); |
| 1790 params.was_within_same_page = navigation_state->was_within_same_page(); |
| 1791 params.security_info = response.securityInfo(); |
| 1792 |
| 1793 // Set the URL to be displayed in the browser UI to the user. |
| 1794 params.url = render_view_->GetLoadingUrl(frame); |
| 1795 DCHECK(!is_swapped_out_ || params.url == GURL(kSwappedOutURL)); |
| 1796 |
| 1797 if (frame->document().baseURL() != params.url) |
| 1798 params.base_url = frame->document().baseURL(); |
| 1799 |
| 1800 GetRedirectChain(ds, ¶ms.redirects); |
| 1801 params.should_update_history = !ds->hasUnreachableURL() && |
| 1802 !response.isMultipartPayload() && (response.httpStatusCode() != 404); |
| 1803 |
| 1804 params.searchable_form_url = internal_data->searchable_form_url(); |
| 1805 params.searchable_form_encoding = internal_data->searchable_form_encoding(); |
| 1806 |
| 1807 params.gesture = render_view_->navigation_gesture_; |
| 1808 render_view_->navigation_gesture_ = NavigationGestureUnknown; |
| 1809 |
| 1810 // Make navigation state a part of the DidCommitProvisionalLoad message so |
| 1811 // that commited entry has it at all times. |
| 1812 WebHistoryItem item = frame->currentHistoryItem(); |
| 1813 if (item.isNull()) { |
| 1814 item.initialize(); |
| 1815 item.setURLString(request.url().spec().utf16()); |
| 1816 } |
| 1817 params.page_state = HistoryItemToPageState(item); |
| 1818 |
| 1819 if (!frame->parent()) { |
| 1820 // Top-level navigation. |
| 1821 |
| 1822 // Reset the zoom limits in case a plugin had changed them previously. This |
| 1823 // will also call us back which will cause us to send a message to |
| 1824 // update WebContentsImpl. |
| 1825 render_view_->webview()->zoomLimitsChanged( |
| 1826 ZoomFactorToZoomLevel(kMinimumZoomFactor), |
| 1827 ZoomFactorToZoomLevel(kMaximumZoomFactor)); |
| 1828 |
| 1829 // Set zoom level, but don't do it for full-page plugin since they don't use |
| 1830 // the same zoom settings. |
| 1831 HostZoomLevels::iterator host_zoom = |
| 1832 render_view_->host_zoom_levels_.find(GURL(request.url())); |
| 1833 if (render_view_->webview()->mainFrame()->document().isPluginDocument()) { |
| 1834 // Reset the zoom levels for plugins. |
| 1835 render_view_->webview()->setZoomLevel(0); |
| 1836 } else { |
| 1837 if (host_zoom != render_view_->host_zoom_levels_.end()) |
| 1838 render_view_->webview()->setZoomLevel(host_zoom->second); |
| 1839 } |
| 1840 |
| 1841 if (host_zoom != render_view_->host_zoom_levels_.end()) { |
| 1842 // This zoom level was merely recorded transiently for this load. We can |
| 1843 // erase it now. If at some point we reload this page, the browser will |
| 1844 // send us a new, up-to-date zoom level. |
| 1845 render_view_->host_zoom_levels_.erase(host_zoom); |
| 1846 } |
| 1847 |
| 1848 // Update contents MIME type for main frame. |
| 1849 params.contents_mime_type = ds->response().mimeType().utf8(); |
| 1850 |
| 1851 params.transition = navigation_state->transition_type(); |
| 1852 if (!PageTransitionIsMainFrame(params.transition)) { |
| 1853 // If the main frame does a load, it should not be reported as a subframe |
| 1854 // navigation. This can occur in the following case: |
| 1855 // 1. You're on a site with frames. |
| 1856 // 2. You do a subframe navigation. This is stored with transition type |
| 1857 // MANUAL_SUBFRAME. |
| 1858 // 3. You navigate to some non-frame site, say, google.com. |
| 1859 // 4. You navigate back to the page from step 2. Since it was initially |
| 1860 // MANUAL_SUBFRAME, it will be that same transition type here. |
| 1861 // We don't want that, because any navigation that changes the toplevel |
| 1862 // frame should be tracked as a toplevel navigation (this allows us to |
| 1863 // update the URL bar, etc). |
| 1864 params.transition = PAGE_TRANSITION_LINK; |
| 1865 } |
| 1866 |
| 1867 // If the page contained a client redirect (meta refresh, document.loc...), |
| 1868 // set the referrer and transition appropriately. |
| 1869 if (ds->isClientRedirect()) { |
| 1870 params.referrer = |
| 1871 Referrer(params.redirects[0], ds->request().referrerPolicy()); |
| 1872 params.transition = static_cast<PageTransition>( |
| 1873 params.transition | PAGE_TRANSITION_CLIENT_REDIRECT); |
| 1874 } else { |
| 1875 params.referrer = RenderViewImpl::GetReferrerFromRequest( |
| 1876 frame, ds->request()); |
| 1877 } |
| 1878 |
| 1879 base::string16 method = request.httpMethod(); |
| 1880 if (EqualsASCII(method, "POST")) { |
| 1881 params.is_post = true; |
| 1882 params.post_id = ExtractPostId(item); |
| 1883 } |
| 1884 |
| 1885 // Send the user agent override back. |
| 1886 params.is_overriding_user_agent = internal_data->is_overriding_user_agent(); |
| 1887 |
| 1888 // Track the URL of the original request. We use the first entry of the |
| 1889 // redirect chain if it exists because the chain may have started in another |
| 1890 // process. |
| 1891 if (params.redirects.size() > 0) |
| 1892 params.original_request_url = params.redirects.at(0); |
| 1893 else |
| 1894 params.original_request_url = original_request.url(); |
| 1895 |
| 1896 params.history_list_was_cleared = |
| 1897 navigation_state->history_list_was_cleared(); |
| 1898 |
| 1899 // Save some histogram data so we can compute the average memory used per |
| 1900 // page load of the glyphs. |
| 1901 UMA_HISTOGRAM_COUNTS_10000("Memory.GlyphPagesPerLoad", |
| 1902 blink::WebGlyphCache::pageCount()); |
| 1903 |
| 1904 // This message needs to be sent before any of allowScripts(), |
| 1905 // allowImages(), allowPlugins() is called for the new page, so that when |
| 1906 // these functions send a ViewHostMsg_ContentBlocked message, it arrives |
| 1907 // after the FrameHostMsg_DidCommitProvisionalLoad message. |
| 1908 Send(new FrameHostMsg_DidCommitProvisionalLoad(routing_id_, params)); |
| 1909 } else { |
| 1910 // Subframe navigation: the type depends on whether this navigation |
| 1911 // generated a new session history entry. When they do generate a session |
| 1912 // history entry, it means the user initiated the navigation and we should |
| 1913 // mark it as such. This test checks if this is the first time UpdateURL |
| 1914 // has been called since WillNavigateToURL was called to initiate the load. |
| 1915 if (render_view_->page_id_ > render_view_->last_page_id_sent_to_browser_) |
| 1916 params.transition = PAGE_TRANSITION_MANUAL_SUBFRAME; |
| 1917 else |
| 1918 params.transition = PAGE_TRANSITION_AUTO_SUBFRAME; |
| 1919 |
| 1920 DCHECK(!navigation_state->history_list_was_cleared()); |
| 1921 params.history_list_was_cleared = false; |
| 1922 |
| 1923 // Don't send this message while the subframe is swapped out. |
| 1924 if (!is_swapped_out()) |
| 1925 Send(new FrameHostMsg_DidCommitProvisionalLoad(routing_id_, params)); |
| 1926 } |
| 1927 |
| 1928 render_view_->last_page_id_sent_to_browser_ = |
| 1929 std::max(render_view_->last_page_id_sent_to_browser_, |
| 1930 render_view_->page_id_); |
| 1931 |
| 1932 // If we end up reusing this WebRequest (for example, due to a #ref click), |
| 1933 // we don't want the transition type to persist. Just clear it. |
| 1934 navigation_state->set_transition_type(PAGE_TRANSITION_LINK); |
| 1935 } |
| 1936 |
1645 } // namespace content | 1937 } // namespace content |
OLD | NEW |