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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 const WebPreferences& webkit_preferences) | 210 const WebPreferences& webkit_preferences) |
211 : RenderWidget(render_thread, true), | 211 : RenderWidget(render_thread, true), |
212 enabled_bindings_(0), | 212 enabled_bindings_(0), |
213 target_url_status_(TARGET_NONE), | 213 target_url_status_(TARGET_NONE), |
214 is_loading_(false), | 214 is_loading_(false), |
215 navigation_gesture_(NavigationGestureUnknown), | 215 navigation_gesture_(NavigationGestureUnknown), |
216 page_id_(-1), | 216 page_id_(-1), |
217 last_page_id_sent_to_browser_(-1), | 217 last_page_id_sent_to_browser_(-1), |
218 last_indexed_page_id_(-1), | 218 last_indexed_page_id_(-1), |
219 opened_by_user_gesture_(true), | 219 opened_by_user_gesture_(true), |
| 220 opener_suppressed_(false), |
220 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), | 221 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), |
221 devtools_agent_(NULL), | 222 devtools_agent_(NULL), |
222 devtools_client_(NULL), | 223 devtools_client_(NULL), |
223 file_chooser_completion_(NULL), | 224 file_chooser_completion_(NULL), |
224 history_back_list_count_(0), | 225 history_back_list_count_(0), |
225 history_forward_list_count_(0), | 226 history_forward_list_count_(0), |
226 has_unload_listener_(false), | 227 has_unload_listener_(false), |
227 decrement_shared_popup_at_destruction_(false), | 228 decrement_shared_popup_at_destruction_(false), |
228 autofill_query_id_(0), | 229 autofill_query_id_(0), |
229 popup_notification_visible_(false), | 230 popup_notification_visible_(false), |
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 // Check to make sure we aren't overloading on popups. | 1283 // Check to make sure we aren't overloading on popups. |
1283 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups) | 1284 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups) |
1284 return NULL; | 1285 return NULL; |
1285 | 1286 |
1286 // This window can't be closed from a window.close() call until we receive a | 1287 // This window can't be closed from a window.close() call until we receive a |
1287 // message from the Browser process explicitly allowing it. | 1288 // message from the Browser process explicitly allowing it. |
1288 popup_notification_visible_ = true; | 1289 popup_notification_visible_ = true; |
1289 | 1290 |
1290 int32 routing_id = MSG_ROUTING_NONE; | 1291 int32 routing_id = MSG_ROUTING_NONE; |
1291 bool user_gesture = creator->isProcessingUserGesture(); | 1292 bool user_gesture = creator->isProcessingUserGesture(); |
| 1293 bool opener_suppressed = creator->willSuppressOpenerInNewFrame(); |
1292 | 1294 |
1293 render_thread_->Send( | 1295 render_thread_->Send( |
1294 new ViewHostMsg_CreateWindow(routing_id_, user_gesture, &routing_id)); | 1296 new ViewHostMsg_CreateWindow(routing_id_, user_gesture, &routing_id)); |
1295 if (routing_id == MSG_ROUTING_NONE) | 1297 if (routing_id == MSG_ROUTING_NONE) |
1296 return NULL; | 1298 return NULL; |
1297 | 1299 |
1298 RenderView* view = RenderView::Create(render_thread_, | 1300 RenderView* view = RenderView::Create(render_thread_, |
1299 0, | 1301 0, |
1300 routing_id_, | 1302 routing_id_, |
1301 renderer_preferences_, | 1303 renderer_preferences_, |
1302 webkit_preferences_, | 1304 webkit_preferences_, |
1303 shared_popup_counter_, | 1305 shared_popup_counter_, |
1304 routing_id); | 1306 routing_id); |
1305 view->opened_by_user_gesture_ = user_gesture; | 1307 view->opened_by_user_gesture_ = user_gesture; |
1306 | 1308 |
| 1309 // Record whether the creator frame is trying to suppress the opener field. |
| 1310 view->opener_suppressed_ = opener_suppressed; |
| 1311 |
1307 // Record the security origin of the creator. | 1312 // Record the security origin of the creator. |
1308 GURL creator_url(creator->securityOrigin().toString().utf8()); | 1313 GURL creator_url(creator->securityOrigin().toString().utf8()); |
1309 if (!creator_url.is_valid() || !creator_url.IsStandard()) | 1314 if (!creator_url.is_valid() || !creator_url.IsStandard()) |
1310 creator_url = GURL(); | 1315 creator_url = GURL(); |
1311 view->creator_url_ = creator_url; | 1316 view->creator_url_ = creator_url; |
1312 | 1317 |
1313 // Copy over the alternate error page URL so we can have alt error pages in | 1318 // Copy over the alternate error page URL so we can have alt error pages in |
1314 // the new render view (we don't need the browser to send the URL back down). | 1319 // the new render view (we don't need the browser to send the URL back down). |
1315 view->alternate_error_page_url_ = alternate_error_page_url_; | 1320 view->alternate_error_page_url_ = alternate_error_page_url_; |
1316 | 1321 |
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1880 // its own process. This is done by sites like Gmail that try to open links | 1885 // its own process. This is done by sites like Gmail that try to open links |
1881 // in new windows without script connections back to the original page. We | 1886 // in new windows without script connections back to the original page. We |
1882 // treat such cases as browser navigations (in which we will create a new | 1887 // treat such cases as browser navigations (in which we will create a new |
1883 // renderer for a cross-site navigation), rather than WebKit navigations. | 1888 // renderer for a cross-site navigation), rather than WebKit navigations. |
1884 // | 1889 // |
1885 // We use the following heuristic to decide whether to fork a new page in its | 1890 // We use the following heuristic to decide whether to fork a new page in its |
1886 // own process: | 1891 // own process: |
1887 // The parent page must open a new tab to about:blank, set the new tab's | 1892 // The parent page must open a new tab to about:blank, set the new tab's |
1888 // window.opener to null, and then redirect the tab to a cross-site URL using | 1893 // window.opener to null, and then redirect the tab to a cross-site URL using |
1889 // JavaScript. | 1894 // JavaScript. |
| 1895 // |
| 1896 // TODO(creis): Deprecate this logic once we can rely on rel=noreferrer |
| 1897 // (see below). |
1890 bool is_fork = | 1898 bool is_fork = |
1891 // Must start from a tab showing about:blank, which is later redirected. | 1899 // Must start from a tab showing about:blank, which is later redirected. |
1892 GURL(frame->url()) == GURL(chrome::kAboutBlankURL) && | 1900 GURL(frame->url()) == GURL(chrome::kAboutBlankURL) && |
1893 // Must be the first real navigation of the tab. | 1901 // Must be the first real navigation of the tab. |
1894 historyBackListCount() < 1 && | 1902 historyBackListCount() < 1 && |
1895 historyForwardListCount() < 1 && | 1903 historyForwardListCount() < 1 && |
1896 // The parent page must have set the child's window.opener to null before | 1904 // The parent page must have set the child's window.opener to null before |
1897 // redirecting to the desired URL. | 1905 // redirecting to the desired URL. |
1898 frame->opener() == NULL && | 1906 frame->opener() == NULL && |
1899 // Must be a top-level frame. | 1907 // Must be a top-level frame. |
1900 frame->parent() == NULL && | 1908 frame->parent() == NULL && |
1901 // Must not have issued the request from this page. | 1909 // Must not have issued the request from this page. |
1902 is_content_initiated && | 1910 is_content_initiated && |
1903 // Must be targeted at the current tab. | 1911 // Must be targeted at the current tab. |
1904 default_policy == WebKit::WebNavigationPolicyCurrentTab && | 1912 default_policy == WebKit::WebNavigationPolicyCurrentTab && |
1905 // Must be a JavaScript navigation, which appears as "other". | 1913 // Must be a JavaScript navigation, which appears as "other". |
1906 type == WebKit::WebNavigationTypeOther; | 1914 type == WebKit::WebNavigationTypeOther; |
1907 if (is_fork) { | 1915 |
| 1916 // Recognize if this navigation is from a link with rel=noreferrer and |
| 1917 // target=_blank attributes, in which case the opener will be suppressed. If |
| 1918 // so, it is safe to load cross-site pages in a separate process, so we |
| 1919 // should let the browser handle it. |
| 1920 bool is_noreferrer_and_blank_target = |
| 1921 // Frame should be top level and not yet navigated. |
| 1922 frame->parent() == NULL && |
| 1923 frame->url().isEmpty() && |
| 1924 historyBackListCount() < 1 && |
| 1925 historyForwardListCount() < 1 && |
| 1926 // Links with rel=noreferrer will have no Referer field, and their |
| 1927 // resulting frame will have its window.opener suppressed. |
| 1928 // TODO(creis): should add a request.httpReferrer() method to help avoid |
| 1929 // typos on the unusual spelling of Referer. |
| 1930 request.httpHeaderField(WebString::fromUTF8("Referer")).isNull() && |
| 1931 opener_suppressed_ && |
| 1932 frame->opener() == NULL && |
| 1933 // Links with target=_blank will have no name. |
| 1934 frame->name().isNull() && |
| 1935 // Another frame (with a non-empty creator) should have initiated the |
| 1936 // request, targeted at this frame. |
| 1937 !creator_url_.is_empty() && |
| 1938 is_content_initiated && |
| 1939 default_policy == WebKit::WebNavigationPolicyCurrentTab && |
| 1940 type == WebKit::WebNavigationTypeOther; |
| 1941 |
| 1942 if (is_fork || is_noreferrer_and_blank_target) { |
1908 // Open the URL via the browser, not via WebKit. | 1943 // Open the URL via the browser, not via WebKit. |
1909 OpenURL(url, GURL(), default_policy); | 1944 OpenURL(url, GURL(), default_policy); |
1910 return WebKit::WebNavigationPolicyIgnore; | 1945 return WebKit::WebNavigationPolicyIgnore; |
1911 } | 1946 } |
1912 | 1947 |
1913 return default_policy; | 1948 return default_policy; |
1914 } | 1949 } |
1915 | 1950 |
1916 bool RenderView::canHandleRequest( | 1951 bool RenderView::canHandleRequest( |
1917 WebFrame* frame, const WebURLRequest& request) { | 1952 WebFrame* frame, const WebURLRequest& request) { |
(...skipping 1729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3647 new PluginMsg_SignalModalDialogEvent(host_window_)); | 3682 new PluginMsg_SignalModalDialogEvent(host_window_)); |
3648 | 3683 |
3649 message->EnableMessagePumping(); // Runs a nested message loop. | 3684 message->EnableMessagePumping(); // Runs a nested message loop. |
3650 bool rv = Send(message); | 3685 bool rv = Send(message); |
3651 | 3686 |
3652 PluginChannelHost::Broadcast( | 3687 PluginChannelHost::Broadcast( |
3653 new PluginMsg_ResetModalDialogEvent(host_window_)); | 3688 new PluginMsg_ResetModalDialogEvent(host_window_)); |
3654 | 3689 |
3655 return rv; | 3690 return rv; |
3656 } | 3691 } |
OLD | NEW |