OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 static const int kDelayForForcedCaptureMs = 6000; | 86 static const int kDelayForForcedCaptureMs = 6000; |
87 | 87 |
88 // How often we will sync the navigation state when the user is changing form | 88 // How often we will sync the navigation state when the user is changing form |
89 // elements or scroll position. | 89 // elements or scroll position. |
90 const TimeDelta kDelayForNavigationSync = TimeDelta::FromSeconds(5); | 90 const TimeDelta kDelayForNavigationSync = TimeDelta::FromSeconds(5); |
91 | 91 |
92 // The next available page ID to use. This ensures that the page IDs are | 92 // The next available page ID to use. This ensures that the page IDs are |
93 // globally unique in the renderer. | 93 // globally unique in the renderer. |
94 static int32 next_page_id_ = 1; | 94 static int32 next_page_id_ = 1; |
95 | 95 |
| 96 // The maximum number of popups that can be spawned from one page. |
| 97 static const int kMaximumNumberOfUnacknowledgedPopups = 25; |
| 98 |
96 static const char* const kUnreachableWebDataURL = | 99 static const char* const kUnreachableWebDataURL = |
97 "chrome-resource://chromewebdata/"; | 100 "chrome-resource://chromewebdata/"; |
98 | 101 |
99 namespace { | 102 namespace { |
100 | 103 |
101 // Associated with browser-initiated navigations to hold tracking data. | 104 // Associated with browser-initiated navigations to hold tracking data. |
102 class RenderViewExtraRequestData : public WebRequest::ExtraData { | 105 class RenderViewExtraRequestData : public WebRequest::ExtraData { |
103 public: | 106 public: |
104 RenderViewExtraRequestData(int32 pending_page_id, | 107 RenderViewExtraRequestData(int32 pending_page_id, |
105 PageTransition::Type transition, | 108 PageTransition::Type transition, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 opened_by_user_gesture_(true), | 146 opened_by_user_gesture_(true), |
144 enable_dom_automation_(false), | 147 enable_dom_automation_(false), |
145 enable_dom_ui_bindings_(false), | 148 enable_dom_ui_bindings_(false), |
146 target_url_status_(TARGET_NONE), | 149 target_url_status_(TARGET_NONE), |
147 printed_document_width_(0), | 150 printed_document_width_(0), |
148 first_default_plugin_(NULL), | 151 first_default_plugin_(NULL), |
149 navigation_gesture_(NavigationGestureUnknown), | 152 navigation_gesture_(NavigationGestureUnknown), |
150 history_back_list_count_(0), | 153 history_back_list_count_(0), |
151 history_forward_list_count_(0), | 154 history_forward_list_count_(0), |
152 disable_popup_blocking_(false), | 155 disable_popup_blocking_(false), |
153 has_unload_listener_(false) { | 156 has_unload_listener_(false), |
| 157 decrement_shared_popup_at_destruction_(false) { |
154 resource_dispatcher_ = new ResourceDispatcher(this); | 158 resource_dispatcher_ = new ResourceDispatcher(this); |
155 #ifdef CHROME_PERSONALIZATION | 159 #ifdef CHROME_PERSONALIZATION |
156 personalization_ = Personalization::CreateRendererPersonalization(); | 160 personalization_ = Personalization::CreateRendererPersonalization(); |
157 #endif | 161 #endif |
158 } | 162 } |
159 | 163 |
160 RenderView::~RenderView() { | 164 RenderView::~RenderView() { |
| 165 if (decrement_shared_popup_at_destruction_) |
| 166 shared_popup_counter_->data--; |
| 167 |
161 resource_dispatcher_->ClearMessageSender(); | 168 resource_dispatcher_->ClearMessageSender(); |
162 // Clear any back-pointers that might still be held by plugins. | 169 // Clear any back-pointers that might still be held by plugins. |
163 PluginDelegateList::iterator it = plugin_delegates_.begin(); | 170 PluginDelegateList::iterator it = plugin_delegates_.begin(); |
164 while (it != plugin_delegates_.end()) { | 171 while (it != plugin_delegates_.end()) { |
165 (*it)->DropRenderView(); | 172 (*it)->DropRenderView(); |
166 it = plugin_delegates_.erase(it); | 173 it = plugin_delegates_.erase(it); |
167 } | 174 } |
168 | 175 |
169 RenderThread::current()->RemoveFilter(debug_message_handler_); | 176 RenderThread::current()->RemoveFilter(debug_message_handler_); |
170 | 177 |
171 #ifdef CHROME_PERSONALIZATION | 178 #ifdef CHROME_PERSONALIZATION |
172 Personalization::CleanupRendererPersonalization(personalization_); | 179 Personalization::CleanupRendererPersonalization(personalization_); |
173 personalization_ = NULL; | 180 personalization_ = NULL; |
174 #endif | 181 #endif |
175 } | 182 } |
176 | 183 |
177 /*static*/ | 184 /*static*/ |
178 RenderView* RenderView::Create(HWND parent_hwnd, | 185 RenderView* RenderView::Create( |
179 HANDLE modal_dialog_event, | 186 HWND parent_hwnd, |
180 int32 opener_id, | 187 HANDLE modal_dialog_event, |
181 const WebPreferences& webkit_prefs, | 188 int32 opener_id, |
182 int32 routing_id) { | 189 const WebPreferences& webkit_prefs, |
| 190 SharedRenderViewCounter* counter, |
| 191 int32 routing_id) { |
183 DCHECK(routing_id != MSG_ROUTING_NONE); | 192 DCHECK(routing_id != MSG_ROUTING_NONE); |
184 scoped_refptr<RenderView> view = new RenderView(); | 193 scoped_refptr<RenderView> view = new RenderView(); |
185 view->Init(parent_hwnd, | 194 view->Init(parent_hwnd, |
186 modal_dialog_event, | 195 modal_dialog_event, |
187 opener_id, | 196 opener_id, |
188 webkit_prefs, | 197 webkit_prefs, |
| 198 counter, |
189 routing_id); // adds reference | 199 routing_id); // adds reference |
190 return view; | 200 return view; |
191 } | 201 } |
192 | 202 |
193 /*static*/ | 203 /*static*/ |
194 void RenderView::SetNextPageID(int32 next_page_id) { | 204 void RenderView::SetNextPageID(int32 next_page_id) { |
195 // This method should only be called during process startup, and the given | 205 // This method should only be called during process startup, and the given |
196 // page id had better not exceed our current next page id! | 206 // page id had better not exceed our current next page id! |
197 DCHECK(next_page_id_ == 1); | 207 DCHECK(next_page_id_ == 1); |
198 DCHECK(next_page_id >= next_page_id_); | 208 DCHECK(next_page_id >= next_page_id_); |
(...skipping 19 matching lines...) Expand all Loading... |
218 | 228 |
219 | 229 |
220 void RenderView::JSOutOfMemory() { | 230 void RenderView::JSOutOfMemory() { |
221 Send(new ViewHostMsg_JSOutOfMemory(routing_id_)); | 231 Send(new ViewHostMsg_JSOutOfMemory(routing_id_)); |
222 } | 232 } |
223 | 233 |
224 void RenderView::Init(HWND parent_hwnd, | 234 void RenderView::Init(HWND parent_hwnd, |
225 HANDLE modal_dialog_event, | 235 HANDLE modal_dialog_event, |
226 int32 opener_id, | 236 int32 opener_id, |
227 const WebPreferences& webkit_prefs, | 237 const WebPreferences& webkit_prefs, |
| 238 SharedRenderViewCounter* counter, |
228 int32 routing_id) { | 239 int32 routing_id) { |
229 DCHECK(!webview()); | 240 DCHECK(!webview()); |
230 | 241 |
231 if (opener_id != MSG_ROUTING_NONE) | 242 if (opener_id != MSG_ROUTING_NONE) |
232 opener_id_ = opener_id; | 243 opener_id_ = opener_id; |
233 | 244 |
| 245 if (counter) { |
| 246 shared_popup_counter_ = counter; |
| 247 shared_popup_counter_->data++; |
| 248 decrement_shared_popup_at_destruction_ = true; |
| 249 } else { |
| 250 shared_popup_counter_ = new SharedRenderViewCounter(0); |
| 251 decrement_shared_popup_at_destruction_ = false; |
| 252 } |
| 253 |
234 // Avoid a leak here by not assigning, since WebView::Create addrefs for us. | 254 // Avoid a leak here by not assigning, since WebView::Create addrefs for us. |
235 WebWidget* view = WebView::Create(this, webkit_prefs); | 255 WebWidget* view = WebView::Create(this, webkit_prefs); |
236 webwidget_.swap(&view); | 256 webwidget_.swap(&view); |
237 | 257 |
238 // Don't let WebCore keep a B/F list - we have our own. | 258 // Don't let WebCore keep a B/F list - we have our own. |
239 // We let it keep 1 entry because FrameLoader::goToItem expects an item in the | 259 // We let it keep 1 entry because FrameLoader::goToItem expects an item in the |
240 // backForwardList, which is used only in ASSERTs. | 260 // backForwardList, which is used only in ASSERTs. |
241 webview()->SetBackForwardListSize(1); | 261 webview()->SetBackForwardListSize(1); |
242 | 262 |
243 routing_id_ = routing_id; | 263 routing_id_ = routing_id; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 IPC_MESSAGE_HANDLER(ViewMsg_ClearAccessibilityInfo, | 353 IPC_MESSAGE_HANDLER(ViewMsg_ClearAccessibilityInfo, |
334 OnClearAccessibilityInfo) | 354 OnClearAccessibilityInfo) |
335 IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose) | 355 IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose) |
336 IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage) | 356 IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage) |
337 IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged) | 357 IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged) |
338 #ifdef CHROME_PERSONALIZATION | 358 #ifdef CHROME_PERSONALIZATION |
339 IPC_MESSAGE_HANDLER(ViewMsg_PersonalizationEvent, OnPersonalizationEvent) | 359 IPC_MESSAGE_HANDLER(ViewMsg_PersonalizationEvent, OnPersonalizationEvent) |
340 #endif | 360 #endif |
341 IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost, | 361 IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost, |
342 OnMessageFromExternalHost) | 362 OnMessageFromExternalHost) |
| 363 IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount, |
| 364 OnDisassociateFromPopupCount) |
343 // Have the super handle all other messages. | 365 // Have the super handle all other messages. |
344 IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message)) | 366 IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message)) |
345 IPC_END_MESSAGE_MAP() | 367 IPC_END_MESSAGE_MAP() |
346 } | 368 } |
347 | 369 |
348 // Got a response from the browser after the renderer decided to create a new | 370 // Got a response from the browser after the renderer decided to create a new |
349 // view. | 371 // view. |
350 void RenderView::OnCreatingNewAck(HWND parent) { | 372 void RenderView::OnCreatingNewAck(HWND parent) { |
351 CompleteInit(parent); | 373 CompleteInit(parent); |
352 } | 374 } |
(...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1639 void RenderView::AddSearchProvider(const std::string& url) { | 1661 void RenderView::AddSearchProvider(const std::string& url) { |
1640 AddGURLSearchProvider(GURL(url), | 1662 AddGURLSearchProvider(GURL(url), |
1641 false); // not autodetected | 1663 false); // not autodetected |
1642 } | 1664 } |
1643 | 1665 |
1644 void RenderView::DebuggerOutput(const std::wstring& out) { | 1666 void RenderView::DebuggerOutput(const std::wstring& out) { |
1645 Send(new ViewHostMsg_DebuggerOutput(routing_id_, out)); | 1667 Send(new ViewHostMsg_DebuggerOutput(routing_id_, out)); |
1646 } | 1668 } |
1647 | 1669 |
1648 WebView* RenderView::CreateWebView(WebView* webview, bool user_gesture) { | 1670 WebView* RenderView::CreateWebView(WebView* webview, bool user_gesture) { |
| 1671 // Check to make sure we aren't overloading on popups. |
| 1672 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups) |
| 1673 return NULL; |
| 1674 |
1649 int32 routing_id = MSG_ROUTING_NONE; | 1675 int32 routing_id = MSG_ROUTING_NONE; |
1650 HANDLE modal_dialog_event = NULL; | 1676 HANDLE modal_dialog_event = NULL; |
1651 bool result = RenderThread::current()->Send( | 1677 bool result = RenderThread::current()->Send( |
1652 new ViewHostMsg_CreateView(routing_id_, user_gesture, &routing_id, | 1678 new ViewHostMsg_CreateView(routing_id_, user_gesture, &routing_id, |
1653 &modal_dialog_event)); | 1679 &modal_dialog_event)); |
1654 if (routing_id == MSG_ROUTING_NONE) { | 1680 if (routing_id == MSG_ROUTING_NONE) { |
1655 DCHECK(modal_dialog_event == NULL); | 1681 DCHECK(modal_dialog_event == NULL); |
1656 return NULL; | 1682 return NULL; |
1657 } | 1683 } |
1658 | 1684 |
1659 // The WebView holds a reference to this new RenderView | 1685 // The WebView holds a reference to this new RenderView |
1660 const WebPreferences& prefs = webview->GetPreferences(); | 1686 const WebPreferences& prefs = webview->GetPreferences(); |
1661 RenderView* view = RenderView::Create(NULL, modal_dialog_event, routing_id_, | 1687 RenderView* view = RenderView::Create(NULL, modal_dialog_event, routing_id_, |
1662 prefs, routing_id); | 1688 prefs, shared_popup_counter_, |
| 1689 routing_id); |
1663 view->set_opened_by_user_gesture(user_gesture); | 1690 view->set_opened_by_user_gesture(user_gesture); |
1664 | 1691 |
1665 // Copy over the alternate error page URL so we can have alt error pages in | 1692 // Copy over the alternate error page URL so we can have alt error pages in |
1666 // the new render view (we don't need the browser to send the URL back down). | 1693 // the new render view (we don't need the browser to send the URL back down). |
1667 view->alternate_error_page_url_ = alternate_error_page_url_; | 1694 view->alternate_error_page_url_ = alternate_error_page_url_; |
1668 | 1695 |
1669 return view->webview(); | 1696 return view->webview(); |
1670 } | 1697 } |
1671 | 1698 |
1672 WebWidget* RenderView::CreatePopupWidget(WebView* webview) { | 1699 WebWidget* RenderView::CreatePopupWidget(WebView* webview) { |
(...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2549 script += "'"; | 2576 script += "'"; |
2550 script += ");void(0);"; | 2577 script += ");void(0);"; |
2551 | 2578 |
2552 GURL script_url(script); | 2579 GURL script_url(script); |
2553 scoped_ptr<WebRequest> request(WebRequest::Create(script_url)); | 2580 scoped_ptr<WebRequest> request(WebRequest::Create(script_url)); |
2554 // TODO(iyengar) | 2581 // TODO(iyengar) |
2555 // Need a mechanism to send results back. | 2582 // Need a mechanism to send results back. |
2556 main_frame->LoadRequest(request.get()); | 2583 main_frame->LoadRequest(request.get()); |
2557 } | 2584 } |
2558 | 2585 |
| 2586 void RenderView::OnDisassociateFromPopupCount() { |
| 2587 if (decrement_shared_popup_at_destruction_) |
| 2588 shared_popup_counter_->data--; |
| 2589 shared_popup_counter_ = new SharedRenderViewCounter(0); |
| 2590 decrement_shared_popup_at_destruction_ = false; |
| 2591 } |
| 2592 |
2559 std::string RenderView::GetAltHTMLForTemplate( | 2593 std::string RenderView::GetAltHTMLForTemplate( |
2560 const DictionaryValue& error_strings, int template_resource_id) const { | 2594 const DictionaryValue& error_strings, int template_resource_id) const { |
2561 const StringPiece template_html( | 2595 const StringPiece template_html( |
2562 ResourceBundle::GetSharedInstance().GetRawDataResource( | 2596 ResourceBundle::GetSharedInstance().GetRawDataResource( |
2563 template_resource_id)); | 2597 template_resource_id)); |
2564 | 2598 |
2565 if (template_html.empty()) { | 2599 if (template_html.empty()) { |
2566 NOTREACHED() << "unable to load template. ID: " << template_resource_id; | 2600 NOTREACHED() << "unable to load template. ID: " << template_resource_id; |
2567 return ""; | 2601 return ""; |
2568 } | 2602 } |
2569 // "t" is the id of the templates root node. | 2603 // "t" is the id of the templates root node. |
2570 return jstemplate_builder::GetTemplateHtml( | 2604 return jstemplate_builder::GetTemplateHtml( |
2571 template_html, &error_strings, "t"); | 2605 template_html, &error_strings, "t"); |
2572 } | 2606 } |
2573 | |
OLD | NEW |