| 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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 const WebPreferences& webkit_preferences) | 209 const WebPreferences& webkit_preferences) |
| 210 : RenderWidget(render_thread, true), | 210 : RenderWidget(render_thread, true), |
| 211 enabled_bindings_(0), | 211 enabled_bindings_(0), |
| 212 target_url_status_(TARGET_NONE), | 212 target_url_status_(TARGET_NONE), |
| 213 is_loading_(false), | 213 is_loading_(false), |
| 214 navigation_gesture_(NavigationGestureUnknown), | 214 navigation_gesture_(NavigationGestureUnknown), |
| 215 page_id_(-1), | 215 page_id_(-1), |
| 216 last_page_id_sent_to_browser_(-1), | 216 last_page_id_sent_to_browser_(-1), |
| 217 last_indexed_page_id_(-1), | 217 last_indexed_page_id_(-1), |
| 218 opened_by_user_gesture_(true), | 218 opened_by_user_gesture_(true), |
| 219 opener_suppressed_(false), |
| 219 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), | 220 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), |
| 220 devtools_agent_(NULL), | 221 devtools_agent_(NULL), |
| 221 devtools_client_(NULL), | 222 devtools_client_(NULL), |
| 222 file_chooser_completion_(NULL), | 223 file_chooser_completion_(NULL), |
| 223 history_back_list_count_(0), | 224 history_back_list_count_(0), |
| 224 history_forward_list_count_(0), | 225 history_forward_list_count_(0), |
| 225 has_unload_listener_(false), | 226 has_unload_listener_(false), |
| 226 decrement_shared_popup_at_destruction_(false), | 227 decrement_shared_popup_at_destruction_(false), |
| 227 autofill_query_id_(0), | 228 autofill_query_id_(0), |
| 228 popup_notification_visible_(false), | 229 popup_notification_visible_(false), |
| (...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1286 // Check to make sure we aren't overloading on popups. | 1287 // Check to make sure we aren't overloading on popups. |
| 1287 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups) | 1288 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups) |
| 1288 return NULL; | 1289 return NULL; |
| 1289 | 1290 |
| 1290 // This window can't be closed from a window.close() call until we receive a | 1291 // This window can't be closed from a window.close() call until we receive a |
| 1291 // message from the Browser process explicitly allowing it. | 1292 // message from the Browser process explicitly allowing it. |
| 1292 popup_notification_visible_ = true; | 1293 popup_notification_visible_ = true; |
| 1293 | 1294 |
| 1294 int32 routing_id = MSG_ROUTING_NONE; | 1295 int32 routing_id = MSG_ROUTING_NONE; |
| 1295 bool user_gesture = creator->isProcessingUserGesture(); | 1296 bool user_gesture = creator->isProcessingUserGesture(); |
| 1297 bool opener_suppressed = creator->willSuppressOpenerInNewFrame(); |
| 1296 | 1298 |
| 1297 render_thread_->Send( | 1299 render_thread_->Send( |
| 1298 new ViewHostMsg_CreateWindow(routing_id_, user_gesture, &routing_id)); | 1300 new ViewHostMsg_CreateWindow(routing_id_, user_gesture, &routing_id)); |
| 1299 if (routing_id == MSG_ROUTING_NONE) | 1301 if (routing_id == MSG_ROUTING_NONE) |
| 1300 return NULL; | 1302 return NULL; |
| 1301 | 1303 |
| 1302 RenderView* view = RenderView::Create(render_thread_, | 1304 RenderView* view = RenderView::Create(render_thread_, |
| 1303 0, | 1305 0, |
| 1304 routing_id_, | 1306 routing_id_, |
| 1305 renderer_preferences_, | 1307 renderer_preferences_, |
| 1306 webkit_preferences_, | 1308 webkit_preferences_, |
| 1307 shared_popup_counter_, | 1309 shared_popup_counter_, |
| 1308 routing_id); | 1310 routing_id); |
| 1309 view->opened_by_user_gesture_ = user_gesture; | 1311 view->opened_by_user_gesture_ = user_gesture; |
| 1310 | 1312 |
| 1313 // Record whether the creator frame is trying to suppress the opener field. |
| 1314 view->opener_suppressed_ = opener_suppressed; |
| 1315 |
| 1311 // Record the security origin of the creator. | 1316 // Record the security origin of the creator. |
| 1312 GURL creator_url(creator->securityOrigin().toString().utf8()); | 1317 GURL creator_url(creator->securityOrigin().toString().utf8()); |
| 1313 if (!creator_url.is_valid() || !creator_url.IsStandard()) | 1318 if (!creator_url.is_valid() || !creator_url.IsStandard()) |
| 1314 creator_url = GURL(); | 1319 creator_url = GURL(); |
| 1315 view->creator_url_ = creator_url; | 1320 view->creator_url_ = creator_url; |
| 1316 | 1321 |
| 1317 // Copy over the alternate error page URL so we can have alt error pages in | 1322 // Copy over the alternate error page URL so we can have alt error pages in |
| 1318 // the new render view (we don't need the browser to send the URL back down). | 1323 // the new render view (we don't need the browser to send the URL back down). |
| 1319 view->alternate_error_page_url_ = alternate_error_page_url_; | 1324 view->alternate_error_page_url_ = alternate_error_page_url_; |
| 1320 | 1325 |
| (...skipping 559 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(const WebKit::WebURLRequest& request) { | 1951 bool RenderView::canHandleRequest(const WebKit::WebURLRequest& request) { |
| 1917 return true; | 1952 return true; |
| (...skipping 1718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3636 new PluginMsg_SignalModalDialogEvent(host_window_)); | 3671 new PluginMsg_SignalModalDialogEvent(host_window_)); |
| 3637 | 3672 |
| 3638 message->EnableMessagePumping(); // Runs a nested message loop. | 3673 message->EnableMessagePumping(); // Runs a nested message loop. |
| 3639 bool rv = Send(message); | 3674 bool rv = Send(message); |
| 3640 | 3675 |
| 3641 PluginChannelHost::Broadcast( | 3676 PluginChannelHost::Broadcast( |
| 3642 new PluginMsg_ResetModalDialogEvent(host_window_)); | 3677 new PluginMsg_ResetModalDialogEvent(host_window_)); |
| 3643 | 3678 |
| 3644 return rv; | 3679 return rv; |
| 3645 } | 3680 } |
| OLD | NEW |