Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/renderer/render_view.h" | 5 #include "chrome/renderer/render_view.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 static int32 next_page_id_ = 1; | 133 static int32 next_page_id_ = 1; |
| 134 | 134 |
| 135 // The maximum number of popups that can be spawned from one page. | 135 // The maximum number of popups that can be spawned from one page. |
| 136 static const int kMaximumNumberOfUnacknowledgedPopups = 25; | 136 static const int kMaximumNumberOfUnacknowledgedPopups = 25; |
| 137 | 137 |
| 138 static const char* const kUnreachableWebDataURL = | 138 static const char* const kUnreachableWebDataURL = |
| 139 "chrome://chromewebdata/"; | 139 "chrome://chromewebdata/"; |
| 140 | 140 |
| 141 static const char* const kBackForwardNavigationScheme = "history"; | 141 static const char* const kBackForwardNavigationScheme = "history"; |
| 142 | 142 |
| 143 namespace { | |
| 144 | |
| 145 // Associated with browser-initiated navigations to hold tracking data. | 143 // Associated with browser-initiated navigations to hold tracking data. |
| 146 class RenderViewExtraRequestData : public WebRequest::ExtraData { | 144 class RenderView::NavigationState : public WebDataSource::ExtraData { |
| 147 public: | 145 public: |
| 148 RenderViewExtraRequestData(int32 pending_page_id, | 146 NavigationState(int32 pending_page_id, |
| 149 PageTransition::Type transition, | 147 PageTransition::Type transition, |
| 150 Time request_time) | 148 Time request_time) |
| 151 : transition_type(transition), | 149 : transition_type(transition), |
| 152 request_time(request_time), | 150 request_time(request_time), |
| 153 request_committed(false), | 151 request_committed(false), |
| 154 pending_page_id_(pending_page_id) { | 152 pending_page_id_(pending_page_id) { |
| 155 } | 153 } |
| 156 | 154 |
| 157 // Contains the page_id for this navigation or -1 if there is none yet. | 155 // Contains the page_id for this navigation or -1 if there is none yet. |
| 158 int32 pending_page_id() const { return pending_page_id_; } | 156 int32 pending_page_id() const { return pending_page_id_; } |
| 159 | 157 |
| 160 // Is this a new navigation? | 158 // Is this a new navigation? |
| 161 bool is_new_navigation() const { return pending_page_id_ == -1; } | 159 bool is_new_navigation() const { return pending_page_id_ == -1; } |
| 162 | 160 |
| 163 // Contains the transition type that the browser specified when it | 161 // Contains the transition type that the browser specified when it |
| 164 // initiated the load. | 162 // initiated the load. |
| 165 PageTransition::Type transition_type; | 163 PageTransition::Type transition_type; |
| 164 | |
| 165 // The time that this navigation was requested. | |
| 166 Time request_time; | 166 Time request_time; |
| 167 | 167 |
| 168 // True if we have already processed the "DidCommitLoad" event for this | 168 // True if we have already processed the "DidCommitLoad" event for this |
| 169 // request. Used by session history. | 169 // request. Used by session history. |
| 170 bool request_committed; | 170 bool request_committed; |
| 171 | 171 |
| 172 private: | 172 private: |
| 173 int32 pending_page_id_; | 173 int32 pending_page_id_; |
| 174 | 174 |
| 175 DISALLOW_COPY_AND_ASSIGN(RenderViewExtraRequestData); | 175 DISALLOW_COPY_AND_ASSIGN(NavigationState); |
| 176 }; | 176 }; |
| 177 | 177 |
| 178 } // namespace | |
| 179 | |
| 180 /////////////////////////////////////////////////////////////////////////////// | 178 /////////////////////////////////////////////////////////////////////////////// |
| 181 | 179 |
| 182 RenderView::RenderView(RenderThreadBase* render_thread) | 180 RenderView::RenderView(RenderThreadBase* render_thread) |
| 183 : RenderWidget(render_thread, true), | 181 : RenderWidget(render_thread, true), |
| 184 enabled_bindings_(0), | 182 enabled_bindings_(0), |
| 185 target_url_status_(TARGET_NONE), | 183 target_url_status_(TARGET_NONE), |
| 186 is_loading_(false), | 184 is_loading_(false), |
| 187 navigation_gesture_(NavigationGestureUnknown), | 185 navigation_gesture_(NavigationGestureUnknown), |
| 188 page_id_(-1), | 186 page_id_(-1), |
| 189 last_page_id_sent_to_browser_(-1), | 187 last_page_id_sent_to_browser_(-1), |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 800 if (is_reload) { | 798 if (is_reload) { |
| 801 cache_policy = WebRequestReloadIgnoringCacheData; | 799 cache_policy = WebRequestReloadIgnoringCacheData; |
| 802 } else if (params.page_id != -1 || main_frame->GetInViewSourceMode()) { | 800 } else if (params.page_id != -1 || main_frame->GetInViewSourceMode()) { |
| 803 cache_policy = WebRequestReturnCacheDataElseLoad; | 801 cache_policy = WebRequestReturnCacheDataElseLoad; |
| 804 } else { | 802 } else { |
| 805 cache_policy = WebRequestUseProtocolCachePolicy; | 803 cache_policy = WebRequestUseProtocolCachePolicy; |
| 806 } | 804 } |
| 807 | 805 |
| 808 scoped_ptr<WebRequest> request(WebRequest::Create(params.url)); | 806 scoped_ptr<WebRequest> request(WebRequest::Create(params.url)); |
| 809 request->SetCachePolicy(cache_policy); | 807 request->SetCachePolicy(cache_policy); |
| 810 request->SetExtraData(new RenderViewExtraRequestData( | 808 |
| 811 params.page_id, params.transition, params.request_time)); | 809 // A navigation resulting from loading a javascript URL should not be treated |
| 810 // as a browser initiated event. Instead, we want it to look as if the page | |
| 811 // initiated any load resulting from JS execution. | |
| 812 if (!params.url.SchemeIs(chrome::kJavaScriptScheme)) { | |
| 813 pending_navigation_state_.reset(new NavigationState( | |
| 814 params.page_id, params.transition, params.request_time)); | |
| 815 } | |
| 812 | 816 |
| 813 // If we are reloading, then WebKit will use the state of the current page. | 817 // If we are reloading, then WebKit will use the state of the current page. |
| 814 // Otherwise, we give it the state to navigate to. | 818 // Otherwise, we give it the state to navigate to. |
| 815 if (!is_reload) | 819 if (!is_reload) |
| 816 request->SetHistoryState(params.state); | 820 request->SetHistoryState(params.state); |
| 817 | 821 |
| 818 if (params.referrer.is_valid()) { | 822 if (params.referrer.is_valid()) { |
| 819 request->SetHttpHeaderValue("Referer", | 823 request->SetHttpHeaderValue("Referer", |
| 820 params.referrer.spec()); | 824 params.referrer.spec()); |
| 821 } | 825 } |
| 822 | 826 |
| 823 main_frame->LoadRequest(request.get()); | 827 main_frame->LoadRequest(request.get()); |
| 828 | |
| 829 // In case LoadRequest failed before DidCreateDataSource was called. | |
| 830 pending_navigation_state_.reset(); | |
| 824 } | 831 } |
| 825 | 832 |
| 826 // Stop loading the current page | 833 // Stop loading the current page |
| 827 void RenderView::OnStop() { | 834 void RenderView::OnStop() { |
| 828 if (webview()) | 835 if (webview()) |
| 829 webview()->StopLoading(); | 836 webview()->StopLoading(); |
| 830 } | 837 } |
| 831 | 838 |
| 832 void RenderView::OnLoadAlternateHTMLText(const std::string& html_contents, | 839 void RenderView::OnLoadAlternateHTMLText(const std::string& html_contents, |
| 833 bool new_navigation, | 840 bool new_navigation, |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 970 | 977 |
| 971 // Tell the embedding application that the URL of the active page has changed | 978 // Tell the embedding application that the URL of the active page has changed |
| 972 void RenderView::UpdateURL(WebFrame* frame) { | 979 void RenderView::UpdateURL(WebFrame* frame) { |
| 973 WebDataSource* ds = frame->GetDataSource(); | 980 WebDataSource* ds = frame->GetDataSource(); |
| 974 DCHECK(ds); | 981 DCHECK(ds); |
| 975 | 982 |
| 976 const WebRequest& request = ds->GetRequest(); | 983 const WebRequest& request = ds->GetRequest(); |
| 977 const WebRequest& initial_request = ds->GetInitialRequest(); | 984 const WebRequest& initial_request = ds->GetInitialRequest(); |
| 978 const WebResponse& response = ds->GetResponse(); | 985 const WebResponse& response = ds->GetResponse(); |
| 979 | 986 |
| 980 // We don't hold a reference to the extra data. The request's reference will | 987 // This will be null if we did not initiate the navigation. |
| 981 // be sufficient because we won't modify it during our call. MAY BE NULL. | 988 NavigationState* navigation_state = |
| 982 RenderViewExtraRequestData* extra_data = | 989 static_cast<NavigationState*>(ds->GetExtraData()); |
| 983 static_cast<RenderViewExtraRequestData*>(request.GetExtraData()); | |
| 984 | 990 |
| 985 ViewHostMsg_FrameNavigate_Params params; | 991 ViewHostMsg_FrameNavigate_Params params; |
| 986 params.http_status_code = response.GetHttpStatusCode(); | 992 params.http_status_code = response.GetHttpStatusCode(); |
| 987 params.is_post = false; | 993 params.is_post = false; |
| 988 params.page_id = page_id_; | 994 params.page_id = page_id_; |
| 989 params.is_content_filtered = response.IsContentFiltered(); | 995 params.is_content_filtered = response.IsContentFiltered(); |
| 990 if (!request.GetSecurityInfo().empty()) { | 996 if (!request.GetSecurityInfo().empty()) { |
| 991 // SSL state specified in the request takes precedence over the one in the | 997 // SSL state specified in the request takes precedence over the one in the |
| 992 // response. | 998 // response. |
| 993 // So far this is only intended for error pages that are not expected to be | 999 // So far this is only intended for error pages that are not expected to be |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1017 } | 1023 } |
| 1018 | 1024 |
| 1019 const PasswordForm* password_form_data = | 1025 const PasswordForm* password_form_data = |
| 1020 frame->GetDataSource()->GetPasswordFormData(); | 1026 frame->GetDataSource()->GetPasswordFormData(); |
| 1021 if (password_form_data) | 1027 if (password_form_data) |
| 1022 params.password_form = *password_form_data; | 1028 params.password_form = *password_form_data; |
| 1023 | 1029 |
| 1024 params.gesture = navigation_gesture_; | 1030 params.gesture = navigation_gesture_; |
| 1025 navigation_gesture_ = NavigationGestureUnknown; | 1031 navigation_gesture_ = NavigationGestureUnknown; |
| 1026 | 1032 |
| 1027 if (webview()->GetMainFrame() == frame) { | 1033 if (!frame->GetParent()) { |
|
brettw
2009/05/20 23:41:04
This is another place you changed the parent thing
darin (slow to review)
2009/05/21 00:06:02
Yeah... cross your fingers for me!
| |
| 1028 // Top-level navigation. | 1034 // Top-level navigation. |
| 1029 | 1035 |
| 1030 // Update contents MIME type for main frame. | 1036 // Update contents MIME type for main frame. |
| 1031 params.contents_mime_type = ds->GetResponse().GetMimeType(); | 1037 params.contents_mime_type = ds->GetResponse().GetMimeType(); |
| 1032 | 1038 |
| 1033 // We assume top level navigations initiated by the renderer are link | 1039 // We assume top level navigations initiated by the renderer are link |
| 1034 // clicks. | 1040 // clicks. |
| 1035 params.transition = extra_data ? | 1041 params.transition = navigation_state ? |
| 1036 extra_data->transition_type : PageTransition::LINK; | 1042 navigation_state->transition_type : PageTransition::LINK; |
| 1037 if (!PageTransition::IsMainFrame(params.transition)) { | 1043 if (!PageTransition::IsMainFrame(params.transition)) { |
| 1038 // If the main frame does a load, it should not be reported as a subframe | 1044 // If the main frame does a load, it should not be reported as a subframe |
| 1039 // navigation. This can occur in the following case: | 1045 // navigation. This can occur in the following case: |
| 1040 // 1. You're on a site with frames. | 1046 // 1. You're on a site with frames. |
| 1041 // 2. You do a subframe navigation. This is stored with transition type | 1047 // 2. You do a subframe navigation. This is stored with transition type |
| 1042 // MANUAL_SUBFRAME. | 1048 // MANUAL_SUBFRAME. |
| 1043 // 3. You navigate to some non-frame site, say, google.com. | 1049 // 3. You navigate to some non-frame site, say, google.com. |
| 1044 // 4. You navigate back to the page from step 2. Since it was initially | 1050 // 4. You navigate back to the page from step 2. Since it was initially |
| 1045 // MANUAL_SUBFRAME, it will be that same transition type here. | 1051 // MANUAL_SUBFRAME, it will be that same transition type here. |
| 1046 // We don't want that, because any navigation that changes the toplevel | 1052 // We don't want that, because any navigation that changes the toplevel |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1077 // Subframe navigation: the type depends on whether this navigation | 1083 // Subframe navigation: the type depends on whether this navigation |
| 1078 // generated a new session history entry. When they do generate a session | 1084 // generated a new session history entry. When they do generate a session |
| 1079 // history entry, it means the user initiated the navigation and we should | 1085 // history entry, it means the user initiated the navigation and we should |
| 1080 // mark it as such. This test checks if this is the first time UpdateURL | 1086 // mark it as such. This test checks if this is the first time UpdateURL |
| 1081 // has been called since WillNavigateToURL was called to initiate the load. | 1087 // has been called since WillNavigateToURL was called to initiate the load. |
| 1082 if (page_id_ > last_page_id_sent_to_browser_) | 1088 if (page_id_ > last_page_id_sent_to_browser_) |
| 1083 params.transition = PageTransition::MANUAL_SUBFRAME; | 1089 params.transition = PageTransition::MANUAL_SUBFRAME; |
| 1084 else | 1090 else |
| 1085 params.transition = PageTransition::AUTO_SUBFRAME; | 1091 params.transition = PageTransition::AUTO_SUBFRAME; |
| 1086 | 1092 |
| 1087 // The browser should never initiate a subframe navigation. | |
| 1088 DCHECK(!extra_data); | |
| 1089 Send(new ViewHostMsg_FrameNavigate(routing_id_, params)); | 1093 Send(new ViewHostMsg_FrameNavigate(routing_id_, params)); |
| 1090 } | 1094 } |
| 1091 | 1095 |
| 1092 last_page_id_sent_to_browser_ = | 1096 last_page_id_sent_to_browser_ = |
| 1093 std::max(last_page_id_sent_to_browser_, page_id_); | 1097 std::max(last_page_id_sent_to_browser_, page_id_); |
| 1094 | 1098 |
| 1095 // If we end up reusing this WebRequest (for example, due to a #ref click), | 1099 // If we end up reusing this WebRequest (for example, due to a #ref click), |
| 1096 // we don't want the transition type to persist. | 1100 // we don't want the transition type to persist. |
| 1097 if (extra_data) | 1101 if (navigation_state) |
| 1098 extra_data->transition_type = PageTransition::LINK; // Just clear it. | 1102 navigation_state->transition_type = PageTransition::LINK; // Just clear it. |
| 1099 | 1103 |
| 1100 #if defined(OS_WIN) | 1104 #if defined(OS_WIN) |
| 1101 if (web_accessibility_manager_.get()) { | 1105 if (web_accessibility_manager_.get()) { |
| 1102 // Clear accessibility info cache. | 1106 // Clear accessibility info cache. |
| 1103 web_accessibility_manager_->ClearAccObjMap(-1, true); | 1107 web_accessibility_manager_->ClearAccObjMap(-1, true); |
| 1104 } | 1108 } |
| 1105 #else | 1109 #else |
| 1106 // TODO(port): accessibility not yet implemented. See http://crbug.com/8288. | 1110 // TODO(port): accessibility not yet implemented. See http://crbug.com/8288. |
| 1107 #endif | 1111 #endif |
| 1108 } | 1112 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1187 kDelayForCaptureMs); | 1191 kDelayForCaptureMs); |
| 1188 | 1192 |
| 1189 // The page is loaded. Try to process the file we need to upload if any. | 1193 // The page is loaded. Try to process the file we need to upload if any. |
| 1190 ProcessPendingUpload(); | 1194 ProcessPendingUpload(); |
| 1191 | 1195 |
| 1192 // Since the page is done loading, we are sure we don't need to try | 1196 // Since the page is done loading, we are sure we don't need to try |
| 1193 // again. | 1197 // again. |
| 1194 ResetPendingUpload(); | 1198 ResetPendingUpload(); |
| 1195 } | 1199 } |
| 1196 | 1200 |
| 1201 void RenderView::DidCreateDataSource(WebFrame* frame, WebDataSource* ds) { | |
| 1202 ds->SetExtraData(pending_navigation_state_.release()); | |
| 1203 } | |
| 1204 | |
| 1197 void RenderView::DidStartProvisionalLoadForFrame( | 1205 void RenderView::DidStartProvisionalLoadForFrame( |
| 1198 WebView* webview, | 1206 WebView* webview, |
| 1199 WebFrame* frame, | 1207 WebFrame* frame, |
| 1200 NavigationGesture gesture) { | 1208 NavigationGesture gesture) { |
| 1201 if (webview->GetMainFrame() == frame) { | 1209 if (webview->GetMainFrame() == frame) { |
| 1202 navigation_gesture_ = gesture; | 1210 navigation_gesture_ = gesture; |
| 1203 | 1211 |
| 1204 // Make sure redirect tracking state is clear for the new load. | 1212 // Make sure redirect tracking state is clear for the new load. |
| 1205 completed_client_redirect_src_ = GURL(); | 1213 completed_client_redirect_src_ = GURL(); |
| 1206 } | 1214 } |
| 1207 | 1215 |
| 1208 WebDataSource* ds = frame->GetProvisionalDataSource(); | 1216 WebDataSource* ds = frame->GetProvisionalDataSource(); |
| 1209 if (ds) { | 1217 if (ds) { |
| 1210 const WebRequest& req = ds->GetRequest(); | 1218 NavigationState* navigation_state = |
| 1211 RenderViewExtraRequestData* extra_data = | 1219 static_cast<NavigationState*>(ds->GetExtraData()); |
| 1212 static_cast<RenderViewExtraRequestData*>(req.GetExtraData()); | 1220 if (navigation_state) |
| 1213 if (extra_data) { | 1221 ds->SetRequestTime(navigation_state->request_time); |
| 1214 ds->SetRequestTime(extra_data->request_time); | |
| 1215 } | |
| 1216 } | 1222 } |
| 1217 Send(new ViewHostMsg_DidStartProvisionalLoadForFrame( | 1223 Send(new ViewHostMsg_DidStartProvisionalLoadForFrame( |
| 1218 routing_id_, webview->GetMainFrame() == frame, | 1224 routing_id_, webview->GetMainFrame() == frame, |
| 1219 frame->GetProvisionalDataSource()->GetRequest().GetURL())); | 1225 frame->GetProvisionalDataSource()->GetRequest().GetURL())); |
| 1220 } | 1226 } |
| 1221 | 1227 |
| 1222 bool RenderView::DidLoadResourceFromMemoryCache(WebView* webview, | 1228 bool RenderView::DidLoadResourceFromMemoryCache(WebView* webview, |
| 1223 const WebRequest& request, | 1229 const WebRequest& request, |
| 1224 const WebResponse& response, | 1230 const WebResponse& response, |
| 1225 WebFrame* frame) { | 1231 WebFrame* frame) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1277 | 1283 |
| 1278 // Don't display an error page if this is simply a cancelled load. Aside | 1284 // Don't display an error page if this is simply a cancelled load. Aside |
| 1279 // from being dumb, WebCore doesn't expect it and it will cause a crash. | 1285 // from being dumb, WebCore doesn't expect it and it will cause a crash. |
| 1280 if (error.GetErrorCode() == net::ERR_ABORTED) | 1286 if (error.GetErrorCode() == net::ERR_ABORTED) |
| 1281 return; | 1287 return; |
| 1282 | 1288 |
| 1283 // If this is a failed back/forward/reload navigation, then we need to do a | 1289 // If this is a failed back/forward/reload navigation, then we need to do a |
| 1284 // 'replace' load. This is necessary to avoid messing up session history. | 1290 // 'replace' load. This is necessary to avoid messing up session history. |
| 1285 // Otherwise, we do a normal load, which simulates a 'go' navigation as far | 1291 // Otherwise, we do a normal load, which simulates a 'go' navigation as far |
| 1286 // as session history is concerned. | 1292 // as session history is concerned. |
| 1287 RenderViewExtraRequestData* extra_data = | 1293 NavigationState* navigation_state = |
| 1288 static_cast<RenderViewExtraRequestData*>(failed_request.GetExtraData()); | 1294 static_cast<NavigationState*>(ds->GetExtraData()); |
| 1289 bool replace = extra_data && !extra_data->is_new_navigation(); | 1295 bool replace = navigation_state && !navigation_state->is_new_navigation(); |
| 1290 | 1296 |
| 1291 // Use the alternate error page service if this is a DNS failure or | 1297 // Use the alternate error page service if this is a DNS failure or |
| 1292 // connection failure. ERR_CONNECTION_FAILED can be dropped once we no longer | 1298 // connection failure. ERR_CONNECTION_FAILED can be dropped once we no longer |
| 1293 // use winhttp. | 1299 // use winhttp. |
| 1294 int ec = error.GetErrorCode(); | 1300 int ec = error.GetErrorCode(); |
| 1295 if (ec == net::ERR_NAME_NOT_RESOLVED || | 1301 if (ec == net::ERR_NAME_NOT_RESOLVED || |
| 1296 ec == net::ERR_CONNECTION_FAILED || | 1302 ec == net::ERR_CONNECTION_FAILED || |
| 1297 ec == net::ERR_CONNECTION_REFUSED || | 1303 ec == net::ERR_CONNECTION_REFUSED || |
| 1298 ec == net::ERR_ADDRESS_UNREACHABLE || | 1304 ec == net::ERR_ADDRESS_UNREACHABLE || |
| 1299 ec == net::ERR_TIMED_OUT) { | 1305 ec == net::ERR_TIMED_OUT) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1346 // Use a data: URL as the site URL to prevent against XSS attacks. | 1352 // Use a data: URL as the site URL to prevent against XSS attacks. |
| 1347 scoped_ptr<WebRequest> request(failed_request->Clone()); | 1353 scoped_ptr<WebRequest> request(failed_request->Clone()); |
| 1348 request->SetURL(GURL(kUnreachableWebDataURL)); | 1354 request->SetURL(GURL(kUnreachableWebDataURL)); |
| 1349 | 1355 |
| 1350 frame->LoadAlternateHTMLString(request.get(), alt_html, failed_url, | 1356 frame->LoadAlternateHTMLString(request.get(), alt_html, failed_url, |
| 1351 replace); | 1357 replace); |
| 1352 } | 1358 } |
| 1353 | 1359 |
| 1354 void RenderView::DidCommitLoadForFrame(WebView *webview, WebFrame* frame, | 1360 void RenderView::DidCommitLoadForFrame(WebView *webview, WebFrame* frame, |
| 1355 bool is_new_navigation) { | 1361 bool is_new_navigation) { |
| 1356 const WebRequest& request = | 1362 NavigationState* navigation_state = static_cast<NavigationState*>( |
| 1357 webview->GetMainFrame()->GetDataSource()->GetRequest(); | 1363 frame->GetDataSource()->GetExtraData()); |
| 1358 RenderViewExtraRequestData* extra_data = | |
| 1359 static_cast<RenderViewExtraRequestData*>(request.GetExtraData()); | |
| 1360 | 1364 |
| 1361 if (is_new_navigation) { | 1365 if (is_new_navigation) { |
| 1362 // When we perform a new navigation, we need to update the previous session | 1366 // When we perform a new navigation, we need to update the previous session |
| 1363 // history entry with state for the page we are leaving. | 1367 // history entry with state for the page we are leaving. |
| 1364 UpdateSessionHistory(frame); | 1368 UpdateSessionHistory(frame); |
| 1365 | 1369 |
| 1366 // We bump our Page ID to correspond with the new session history entry. | 1370 // We bump our Page ID to correspond with the new session history entry. |
| 1367 page_id_ = next_page_id_++; | 1371 page_id_ = next_page_id_++; |
| 1368 | 1372 |
| 1369 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 1373 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 1370 method_factory_.NewRunnableMethod(&RenderView::CapturePageInfo, | 1374 method_factory_.NewRunnableMethod(&RenderView::CapturePageInfo, |
| 1371 page_id_, true), | 1375 page_id_, true), |
| 1372 kDelayForForcedCaptureMs); | 1376 kDelayForForcedCaptureMs); |
| 1373 } else { | 1377 } else { |
| 1374 // Inspect the extra_data on the main frame (set in our Navigate method) to | 1378 // Inspect the navigation_state on the main frame (set in our Navigate |
| 1375 // see if the navigation corresponds to a session history navigation... | 1379 // method) to see if the navigation corresponds to a session history |
| 1376 // Note: |frame| may or may not be the toplevel frame, but for the case | 1380 // navigation... Note: |frame| may or may not be the toplevel frame, but |
| 1377 // of capturing session history, the first committed frame suffices. We | 1381 // for the case of capturing session history, the first committed frame |
| 1378 // keep track of whether we've seen this commit before so that only capture | 1382 // suffices. We keep track of whether we've seen this commit before so |
| 1379 // session history once per navigation. | 1383 // that only capture session history once per navigation. |
| 1380 // | 1384 // |
| 1381 // Note that we need to check if the page ID changed. In the case of a | 1385 // Note that we need to check if the page ID changed. In the case of a |
| 1382 // reload, the page ID doesn't change, and UpdateSessionHistory gets the | 1386 // reload, the page ID doesn't change, and UpdateSessionHistory gets the |
| 1383 // previous URL and the current page ID, which would be wrong. | 1387 // previous URL and the current page ID, which would be wrong. |
| 1384 if (extra_data && !extra_data->is_new_navigation() && | 1388 if (navigation_state && !navigation_state->is_new_navigation() && |
| 1385 !extra_data->request_committed && | 1389 !navigation_state->request_committed && |
| 1386 page_id_ != extra_data->pending_page_id()) { | 1390 page_id_ != navigation_state->pending_page_id()) { |
| 1387 // This is a successful session history navigation! | 1391 // This is a successful session history navigation! |
| 1388 UpdateSessionHistory(frame); | 1392 UpdateSessionHistory(frame); |
| 1389 page_id_ = extra_data->pending_page_id(); | 1393 page_id_ = navigation_state->pending_page_id(); |
| 1390 } | 1394 } |
| 1391 } | 1395 } |
| 1392 | 1396 |
| 1393 // Remember that we've already processed this request, so we don't update | 1397 // Remember that we've already processed this request, so we don't update |
| 1394 // the session history again. We do this regardless of whether this is | 1398 // the session history again. We do this regardless of whether this is |
| 1395 // a session history navigation, because if we attempted a session history | 1399 // a session history navigation, because if we attempted a session history |
| 1396 // navigation without valid HistoryItem state, WebCore will think it is a | 1400 // navigation without valid HistoryItem state, WebCore will think it is a |
| 1397 // new navigation. | 1401 // new navigation. |
| 1398 if (extra_data) | 1402 if (navigation_state) |
| 1399 extra_data->request_committed = true; | 1403 navigation_state->request_committed = true; |
| 1400 | 1404 |
| 1401 UpdateURL(frame); | 1405 UpdateURL(frame); |
| 1402 | 1406 |
| 1403 // If this committed load was initiated by a client redirect, we're | 1407 // If this committed load was initiated by a client redirect, we're |
| 1404 // at the last stop now, so clear it. | 1408 // at the last stop now, so clear it. |
| 1405 completed_client_redirect_src_ = GURL(); | 1409 completed_client_redirect_src_ = GURL(); |
| 1406 | 1410 |
| 1407 // Check whether we have new encoding name. | 1411 // Check whether we have new encoding name. |
| 1408 UpdateEncoding(frame, webview->GetMainFrameEncodingName()); | 1412 UpdateEncoding(frame, webview->GetMainFrameEncodingName()); |
| 1409 } | 1413 } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1440 frame, UserScript::DOCUMENT_END); | 1444 frame, UserScript::DOCUMENT_END); |
| 1441 } | 1445 } |
| 1442 | 1446 |
| 1443 void RenderView::DidHandleOnloadEventsForFrame(WebView* webview, | 1447 void RenderView::DidHandleOnloadEventsForFrame(WebView* webview, |
| 1444 WebFrame* frame) { | 1448 WebFrame* frame) { |
| 1445 } | 1449 } |
| 1446 | 1450 |
| 1447 void RenderView::DidChangeLocationWithinPageForFrame(WebView* webview, | 1451 void RenderView::DidChangeLocationWithinPageForFrame(WebView* webview, |
| 1448 WebFrame* frame, | 1452 WebFrame* frame, |
| 1449 bool is_new_navigation) { | 1453 bool is_new_navigation) { |
| 1454 // If this was a reference fragment navigation that we initiated, then we | |
| 1455 // could end up having a non-null pending navigation state. We just need to | |
| 1456 // update the ExtraData on the datasource so that others who read the | |
| 1457 // ExtraData will get the new NavigationState. Similarly, if we did not | |
| 1458 // initiate this navigation, then we need to take care to clear any pre- | |
| 1459 // existing navigation state. | |
| 1460 frame->GetDataSource()->SetExtraData(pending_navigation_state_.release()); | |
| 1461 | |
| 1450 DidCommitLoadForFrame(webview, frame, is_new_navigation); | 1462 DidCommitLoadForFrame(webview, frame, is_new_navigation); |
| 1463 | |
| 1451 const string16& title = | 1464 const string16& title = |
| 1452 webview->GetMainFrame()->GetDataSource()->GetPageTitle(); | 1465 webview->GetMainFrame()->GetDataSource()->GetPageTitle(); |
| 1453 UpdateTitle(frame, UTF16ToWideHack(title)); | 1466 UpdateTitle(frame, UTF16ToWideHack(title)); |
| 1454 } | 1467 } |
| 1455 | 1468 |
| 1456 void RenderView::DidReceiveIconForFrame(WebView* webview, | 1469 void RenderView::DidReceiveIconForFrame(WebView* webview, |
| 1457 WebFrame* frame) { | 1470 WebFrame* frame) { |
| 1458 } | 1471 } |
| 1459 | 1472 |
| 1460 void RenderView::WillPerformClientRedirect(WebView* webview, | 1473 void RenderView::WillPerformClientRedirect(WebView* webview, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1543 frame, UserScript::DOCUMENT_START); | 1556 frame, UserScript::DOCUMENT_START); |
| 1544 } | 1557 } |
| 1545 | 1558 |
| 1546 WindowOpenDisposition RenderView::DispositionForNavigationAction( | 1559 WindowOpenDisposition RenderView::DispositionForNavigationAction( |
| 1547 WebView* webview, | 1560 WebView* webview, |
| 1548 WebFrame* frame, | 1561 WebFrame* frame, |
| 1549 const WebRequest* request, | 1562 const WebRequest* request, |
| 1550 WebNavigationType type, | 1563 WebNavigationType type, |
| 1551 WindowOpenDisposition disposition, | 1564 WindowOpenDisposition disposition, |
| 1552 bool is_redirect) { | 1565 bool is_redirect) { |
| 1566 // GetExtraData is NULL when we did not issue the request ourselves (see | |
| 1567 // OnNavigate), and so such a request may correspond to a link-click, | |
| 1568 // script, or drag-n-drop initiated navigation. | |
| 1569 bool is_content_initiated = | |
| 1570 !frame->GetProvisionalDataSource()->GetExtraData(); | |
| 1571 | |
| 1553 // Webkit is asking whether to navigate to a new URL. | 1572 // Webkit is asking whether to navigate to a new URL. |
| 1554 // This is fine normally, except if we're showing UI from one security | 1573 // This is fine normally, except if we're showing UI from one security |
| 1555 // context and they're trying to navigate to a different context. | 1574 // context and they're trying to navigate to a different context. |
| 1556 const GURL& url = request->GetURL(); | 1575 const GURL& url = request->GetURL(); |
| 1576 | |
| 1557 // We only care about navigations that are within the current tab (as opposed | 1577 // We only care about navigations that are within the current tab (as opposed |
| 1558 // to, for example, opening a new window). | 1578 // to, for example, opening a new window). |
| 1559 // But we sometimes navigate to about:blank to clear a tab, and we want to | 1579 // But we sometimes navigate to about:blank to clear a tab, and we want to |
| 1560 // still allow that. | 1580 // still allow that. |
| 1561 if (disposition == CURRENT_TAB && !(url.SchemeIs(chrome::kAboutScheme))) { | 1581 if (disposition == CURRENT_TAB && is_content_initiated && |
| 1562 // GetExtraData is NULL when we did not issue the request ourselves (see | 1582 frame->GetParent() == NULL && !url.SchemeIs(chrome::kAboutScheme)) { |
| 1563 // OnNavigate), and so such a request may correspond to a link-click, | 1583 // When we received such unsolicited navigations, we sometimes want to |
| 1564 // script, or drag-n-drop initiated navigation. | 1584 // punt them up to the browser to handle. |
| 1565 if (frame == webview->GetMainFrame() && !request->GetExtraData()) { | 1585 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_) || |
| 1566 // When we received such unsolicited navigations, we sometimes want to | 1586 frame->GetInViewSourceMode() || |
| 1567 // punt them up to the browser to handle. | 1587 url.SchemeIs(chrome::kViewSourceScheme)) { |
| 1568 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_) || | 1588 OpenURL(webview, url, GURL(), disposition); |
| 1569 frame->GetInViewSourceMode() || | 1589 return IGNORE_ACTION; // Suppress the load here. |
| 1570 url.SchemeIs(chrome::kViewSourceScheme)) { | |
| 1571 OpenURL(webview, url, GURL(), disposition); | |
| 1572 return IGNORE_ACTION; // Suppress the load here. | |
| 1573 } | |
| 1574 } | 1590 } |
| 1575 } | 1591 } |
| 1576 | 1592 |
| 1577 // Detect when a page is "forking" a new tab that can be safely rendered in | 1593 // Detect when a page is "forking" a new tab that can be safely rendered in |
| 1578 // its own process. This is done by sites like Gmail that try to open links | 1594 // its own process. This is done by sites like Gmail that try to open links |
| 1579 // in new windows without script connections back to the original page. We | 1595 // in new windows without script connections back to the original page. We |
| 1580 // treat such cases as browser navigations (in which we will create a new | 1596 // treat such cases as browser navigations (in which we will create a new |
| 1581 // renderer for a cross-site navigation), rather than WebKit navigations. | 1597 // renderer for a cross-site navigation), rather than WebKit navigations. |
| 1582 // | 1598 // |
| 1583 // We use the following heuristic to decide whether to fork a new page in its | 1599 // We use the following heuristic to decide whether to fork a new page in its |
| 1584 // own process: | 1600 // own process: |
| 1585 // The parent page must open a new tab to about:blank, set the new tab's | 1601 // The parent page must open a new tab to about:blank, set the new tab's |
| 1586 // window.opener to null, and then redirect the tab to a cross-site URL using | 1602 // window.opener to null, and then redirect the tab to a cross-site URL using |
| 1587 // JavaScript. | 1603 // JavaScript. |
| 1588 bool is_fork = | 1604 bool is_fork = |
| 1589 // Must start from a tab showing about:blank, which is later redirected. | 1605 // Must start from a tab showing about:blank, which is later redirected. |
| 1590 frame->GetURL() == GURL("about:blank") && | 1606 frame->GetURL() == GURL("about:blank") && |
| 1591 // Must be the first real navigation of the tab. | 1607 // Must be the first real navigation of the tab. |
| 1592 GetHistoryBackListCount() < 1 && | 1608 GetHistoryBackListCount() < 1 && |
| 1593 GetHistoryForwardListCount() < 1 && | 1609 GetHistoryForwardListCount() < 1 && |
| 1594 // The parent page must have set the child's window.opener to null before | 1610 // The parent page must have set the child's window.opener to null before |
| 1595 // redirecting to the desired URL. | 1611 // redirecting to the desired URL. |
| 1596 frame->GetOpener() == NULL && | 1612 frame->GetOpener() == NULL && |
| 1597 // Must be a top-level frame. | 1613 // Must be a top-level frame. |
| 1598 frame->GetParent() == NULL && | 1614 frame->GetParent() == NULL && |
| 1599 // Must not have issued the request from this page. GetExtraData is NULL | 1615 // Must not have issued the request from this page. |
| 1600 // when the navigation is being done by something outside the page. | 1616 is_content_initiated && |
| 1601 !request->GetExtraData() && | |
| 1602 // Must be targeted at the current tab. | 1617 // Must be targeted at the current tab. |
| 1603 disposition == CURRENT_TAB && | 1618 disposition == CURRENT_TAB && |
| 1604 // Must be a JavaScript navigation, which appears as "other". | 1619 // Must be a JavaScript navigation, which appears as "other". |
| 1605 type == WebNavigationTypeOther; | 1620 type == WebNavigationTypeOther; |
| 1606 if (is_fork) { | 1621 if (is_fork) { |
| 1607 // Open the URL via the browser, not via WebKit. | 1622 // Open the URL via the browser, not via WebKit. |
| 1608 OpenURL(webview, url, GURL(), disposition); | 1623 OpenURL(webview, url, GURL(), disposition); |
| 1609 return IGNORE_ACTION; | 1624 return IGNORE_ACTION; |
| 1610 } | 1625 } |
| 1611 | 1626 |
| (...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2855 | 2870 |
| 2856 void RenderView::DidAddHistoryItem() { | 2871 void RenderView::DidAddHistoryItem() { |
| 2857 // We don't want to update the history length for the start page | 2872 // We don't want to update the history length for the start page |
| 2858 // navigation. | 2873 // navigation. |
| 2859 WebFrame* main_frame = webview()->GetMainFrame(); | 2874 WebFrame* main_frame = webview()->GetMainFrame(); |
| 2860 DCHECK(main_frame != NULL); | 2875 DCHECK(main_frame != NULL); |
| 2861 | 2876 |
| 2862 WebDataSource* ds = main_frame->GetDataSource(); | 2877 WebDataSource* ds = main_frame->GetDataSource(); |
| 2863 DCHECK(ds != NULL); | 2878 DCHECK(ds != NULL); |
| 2864 | 2879 |
| 2865 const WebRequest& request = ds->GetRequest(); | 2880 NavigationState* navigation_state = |
| 2866 RenderViewExtraRequestData* extra_data = | 2881 static_cast<NavigationState*>(ds->GetExtraData()); |
| 2867 static_cast<RenderViewExtraRequestData*>(request.GetExtraData()); | |
| 2868 | 2882 |
| 2869 if (extra_data && extra_data->transition_type == PageTransition::START_PAGE) | 2883 if (navigation_state && |
| 2884 navigation_state->transition_type == PageTransition::START_PAGE) | |
| 2870 return; | 2885 return; |
| 2871 | 2886 |
| 2872 history_back_list_count_++; | 2887 history_back_list_count_++; |
| 2873 history_forward_list_count_ = 0; | 2888 history_forward_list_count_ = 0; |
| 2874 } | 2889 } |
| 2875 | 2890 |
| 2876 void RenderView::OnMessageFromExternalHost(const std::string& message, | 2891 void RenderView::OnMessageFromExternalHost(const std::string& message, |
| 2877 const std::string& origin, | 2892 const std::string& origin, |
| 2878 const std::string& target) { | 2893 const std::string& target) { |
| 2879 if (message.empty()) | 2894 if (message.empty()) |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3017 } | 3032 } |
| 3018 } | 3033 } |
| 3019 UMA_HISTOGRAM_TIMES("Renderer.All.StartToFinishDoc", start_to_finish_doc); | 3034 UMA_HISTOGRAM_TIMES("Renderer.All.StartToFinishDoc", start_to_finish_doc); |
| 3020 UMA_HISTOGRAM_TIMES("Renderer.All.FinishDocToFinish", finish_doc_to_finish); | 3035 UMA_HISTOGRAM_TIMES("Renderer.All.FinishDocToFinish", finish_doc_to_finish); |
| 3021 UMA_HISTOGRAM_TIMES("Renderer.All.StartToFinish", start_to_finish); | 3036 UMA_HISTOGRAM_TIMES("Renderer.All.StartToFinish", start_to_finish); |
| 3022 if (start_to_first_layout.ToInternalValue() >= 0) { | 3037 if (start_to_first_layout.ToInternalValue() >= 0) { |
| 3023 UMA_HISTOGRAM_TIMES( | 3038 UMA_HISTOGRAM_TIMES( |
| 3024 "Renderer.All.StartToFirstLayout", start_to_first_layout); | 3039 "Renderer.All.StartToFirstLayout", start_to_first_layout); |
| 3025 } | 3040 } |
| 3026 } | 3041 } |
| OLD | NEW |