Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_view.h" | 5 #include "content/renderer/render_view.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/callback.h" | 12 #include "base/callback.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
| 15 #include "base/i18n/rtl.h" | |
| 15 #include "base/json/json_writer.h" | 16 #include "base/json/json_writer.h" |
| 16 #include "base/lazy_instance.h" | 17 #include "base/lazy_instance.h" |
| 17 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram.h" |
| 18 #include "base/path_service.h" | 19 #include "base/path_service.h" |
| 19 #include "base/process_util.h" | 20 #include "base/process_util.h" |
| 20 #include "base/string_piece.h" | 21 #include "base/string_piece.h" |
| 21 #include "base/string_util.h" | 22 #include "base/string_util.h" |
| 22 #include "base/sys_string_conversions.h" | 23 #include "base/sys_string_conversions.h" |
| 23 #include "base/time.h" | 24 #include "base/time.h" |
| 24 #include "base/utf_string_conversions.h" | 25 #include "base/utf_string_conversions.h" |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 using base::TimeDelta; | 236 using base::TimeDelta; |
| 236 using webkit_glue::AltErrorPageResourceFetcher; | 237 using webkit_glue::AltErrorPageResourceFetcher; |
| 237 using webkit_glue::FormField; | 238 using webkit_glue::FormField; |
| 238 using webkit_glue::PasswordForm; | 239 using webkit_glue::PasswordForm; |
| 239 using webkit_glue::PasswordFormDomManager; | 240 using webkit_glue::PasswordFormDomManager; |
| 240 using webkit_glue::ResourceFetcher; | 241 using webkit_glue::ResourceFetcher; |
| 241 using webkit_glue::WebAccessibility; | 242 using webkit_glue::WebAccessibility; |
| 242 | 243 |
| 243 //----------------------------------------------------------------------------- | 244 //----------------------------------------------------------------------------- |
| 244 | 245 |
| 246 namespace { | |
| 247 | |
| 248 // Return true if the character is known to be a strong LTR character. | |
| 249 // A false return value can mean it's not an LTR character or just that | |
| 250 // it's a strongly LTR character not in the set we test. | |
| 251 // Used as a fast-path for the common case of LTR text. | |
| 252 bool IsStronglyLTR(char16 ch) { | |
|
brettw
2011/07/29 17:14:00
If the check in rtl.h is slow, it seems like it mi
Evan Martin
2011/07/30 00:05:15
It's more that the function in rtl.h actually scan
| |
| 253 return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); | |
| 254 } | |
| 255 | |
| 256 } // namespace | |
| 257 | |
| 245 typedef std::map<WebKit::WebView*, RenderView*> ViewMap; | 258 typedef std::map<WebKit::WebView*, RenderView*> ViewMap; |
| 246 static base::LazyInstance<ViewMap> g_view_map(base::LINKER_INITIALIZED); | 259 static base::LazyInstance<ViewMap> g_view_map(base::LINKER_INITIALIZED); |
| 247 | 260 |
| 248 // Time, in seconds, we delay before sending content state changes (such as form | 261 // Time, in seconds, we delay before sending content state changes (such as form |
| 249 // state and scroll position) to the browser. We delay sending changes to avoid | 262 // state and scroll position) to the browser. We delay sending changes to avoid |
| 250 // spamming the browser. | 263 // spamming the browser. |
| 251 // To avoid having tab/session restore require sending a message to get the | 264 // To avoid having tab/session restore require sending a message to get the |
| 252 // current content state during tab closing we use a shorter timeout for the | 265 // current content state during tab closing we use a shorter timeout for the |
| 253 // foreground renderer. This means there is a small window of time from which | 266 // foreground renderer. This means there is a small window of time from which |
| 254 // content state is modified and not sent to session restore, but this is | 267 // content state is modified and not sent to session restore, but this is |
| (...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1170 | 1183 |
| 1171 // Check if the navigation was within the same page, in which case we don't | 1184 // Check if the navigation was within the same page, in which case we don't |
| 1172 // want to clear the accessibility cache. | 1185 // want to clear the accessibility cache. |
| 1173 if (accessibility_.get() && !navigation_state->was_within_same_page()) { | 1186 if (accessibility_.get() && !navigation_state->was_within_same_page()) { |
| 1174 accessibility_.reset(); | 1187 accessibility_.reset(); |
| 1175 pending_accessibility_notifications_.clear(); | 1188 pending_accessibility_notifications_.clear(); |
| 1176 } | 1189 } |
| 1177 } | 1190 } |
| 1178 | 1191 |
| 1179 // Tell the embedding application that the title of the active page has changed | 1192 // Tell the embedding application that the title of the active page has changed |
| 1180 void RenderView::UpdateTitle(WebFrame* frame, const string16& title) { | 1193 void RenderView::UpdateTitle(WebFrame* frame, const string16& title, |
| 1181 // Ignore all but top level navigations... | 1194 WebTextDirection title_direction) { |
| 1182 if (!frame->parent()) { | 1195 // Ignore all but top level navigations. |
| 1183 Send(new ViewHostMsg_UpdateTitle( | 1196 if (frame->parent()) |
| 1184 routing_id_, | 1197 return; |
| 1185 page_id_, | 1198 |
| 1186 title.length() > content::kMaxTitleChars ? | 1199 string16 fixed_title = title.substr(0, content::kMaxTitleChars); |
| 1187 title.substr(0, content::kMaxTitleChars) : title)); | 1200 |
| 1201 // Wrap with extra Unicode formatting to make the title strongly directional. | |
| 1202 if (!fixed_title.empty()) { | |
| 1203 if (title_direction == WebKit::WebTextDirectionLeftToRight) { | |
| 1204 // To avoid needing to complicate tests that only use ASCII characters, | |
| 1205 // special-case out some known strongly directional characters. | |
| 1206 if (!IsStronglyLTR(title[0])) | |
| 1207 base::i18n::WrapStringWithLTRFormatting(&fixed_title); | |
| 1208 } else { | |
| 1209 base::i18n::WrapStringWithRTLFormatting(&fixed_title); | |
| 1210 } | |
| 1188 } | 1211 } |
| 1212 | |
| 1213 Send(new ViewHostMsg_UpdateTitle(routing_id_, page_id_, fixed_title)); | |
| 1189 } | 1214 } |
| 1190 | 1215 |
| 1191 void RenderView::UpdateEncoding(WebFrame* frame, | 1216 void RenderView::UpdateEncoding(WebFrame* frame, |
| 1192 const std::string& encoding_name) { | 1217 const std::string& encoding_name) { |
| 1193 // Only update main frame's encoding_name. | 1218 // Only update main frame's encoding_name. |
| 1194 if (webview()->mainFrame() == frame && | 1219 if (webview()->mainFrame() == frame && |
| 1195 last_encoding_name_ != encoding_name) { | 1220 last_encoding_name_ != encoding_name) { |
| 1196 // Save the encoding name for later comparing. | 1221 // Save the encoding name for later comparing. |
| 1197 last_encoding_name_ = encoding_name; | 1222 last_encoding_name_ = encoding_name; |
| 1198 | 1223 |
| (...skipping 1324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2523 if (frame == webview()->mainFrame()) | 2548 if (frame == webview()->mainFrame()) |
| 2524 Send(new ViewHostMsg_DocumentAvailableInMainFrame(routing_id_)); | 2549 Send(new ViewHostMsg_DocumentAvailableInMainFrame(routing_id_)); |
| 2525 } | 2550 } |
| 2526 | 2551 |
| 2527 FOR_EACH_OBSERVER(RenderViewObserver, observers_, | 2552 FOR_EACH_OBSERVER(RenderViewObserver, observers_, |
| 2528 DidCreateDocumentElement(frame)); | 2553 DidCreateDocumentElement(frame)); |
| 2529 } | 2554 } |
| 2530 | 2555 |
| 2531 void RenderView::didReceiveTitle(WebFrame* frame, const WebString& title, | 2556 void RenderView::didReceiveTitle(WebFrame* frame, const WebString& title, |
| 2532 WebTextDirection direction) { | 2557 WebTextDirection direction) { |
| 2533 // TODO: pass direction through various APIs. | 2558 UpdateTitle(frame, title, direction); |
| 2534 // http://code.google.com/p/chromium/issues/detail?id=79903 | |
| 2535 UpdateTitle(frame, title); | |
| 2536 | 2559 |
| 2537 // Also check whether we have new encoding name. | 2560 // Also check whether we have new encoding name. |
| 2538 UpdateEncoding(frame, frame->view()->pageEncoding().utf8()); | 2561 UpdateEncoding(frame, frame->view()->pageEncoding().utf8()); |
| 2539 } | 2562 } |
| 2540 | 2563 |
| 2541 void RenderView::didChangeIcon(WebFrame* frame, WebIconURL::Type type) { | 2564 void RenderView::didChangeIcon(WebFrame* frame, WebIconURL::Type type) { |
| 2542 FOR_EACH_OBSERVER(RenderViewObserver, observers_, | 2565 FOR_EACH_OBSERVER(RenderViewObserver, observers_, |
| 2543 DidChangeIcon(frame, type)); | 2566 DidChangeIcon(frame, type)); |
| 2544 } | 2567 } |
| 2545 | 2568 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2590 // existing navigation state to a content-initiated navigation state. | 2613 // existing navigation state to a content-initiated navigation state. |
| 2591 // DidCreateDataSource conveniently takes care of this for us. | 2614 // DidCreateDataSource conveniently takes care of this for us. |
| 2592 didCreateDataSource(frame, frame->dataSource()); | 2615 didCreateDataSource(frame, frame->dataSource()); |
| 2593 | 2616 |
| 2594 NavigationState* new_state = | 2617 NavigationState* new_state = |
| 2595 NavigationState::FromDataSource(frame->dataSource()); | 2618 NavigationState::FromDataSource(frame->dataSource()); |
| 2596 new_state->set_was_within_same_page(true); | 2619 new_state->set_was_within_same_page(true); |
| 2597 | 2620 |
| 2598 didCommitProvisionalLoad(frame, is_new_navigation); | 2621 didCommitProvisionalLoad(frame, is_new_navigation); |
| 2599 | 2622 |
| 2600 UpdateTitle(frame, frame->view()->mainFrame()->dataSource()->pageTitle()); | 2623 // TODO(evan): update this to use ->pageTitleDirection() once we pull in new |
| 2624 // WebKit. | |
| 2625 // http://code.google.com/p/chromium/issues/detail?id=27094 | |
| 2626 UpdateTitle(frame, frame->view()->mainFrame()->dataSource()->pageTitle(), | |
| 2627 WebKit::WebTextDirectionLeftToRight); | |
| 2601 } | 2628 } |
| 2602 | 2629 |
| 2603 void RenderView::didUpdateCurrentHistoryItem(WebFrame* frame) { | 2630 void RenderView::didUpdateCurrentHistoryItem(WebFrame* frame) { |
| 2604 StartNavStateSyncTimerIfNecessary(); | 2631 StartNavStateSyncTimerIfNecessary(); |
| 2605 } | 2632 } |
| 2606 | 2633 |
| 2607 void RenderView::assignIdentifierToRequest( | 2634 void RenderView::assignIdentifierToRequest( |
| 2608 WebFrame* frame, unsigned identifier, const WebURLRequest& request) { | 2635 WebFrame* frame, unsigned identifier, const WebURLRequest& request) { |
| 2609 // Ignore | 2636 // Ignore |
| 2610 } | 2637 } |
| (...skipping 1778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4389 } | 4416 } |
| 4390 #endif | 4417 #endif |
| 4391 | 4418 |
| 4392 void RenderView::OnContextMenuClosed( | 4419 void RenderView::OnContextMenuClosed( |
| 4393 const webkit_glue::CustomContextMenuContext& custom_context) { | 4420 const webkit_glue::CustomContextMenuContext& custom_context) { |
| 4394 if (custom_context.is_pepper_menu) | 4421 if (custom_context.is_pepper_menu) |
| 4395 pepper_delegate_.OnContextMenuClosed(custom_context); | 4422 pepper_delegate_.OnContextMenuClosed(custom_context); |
| 4396 else | 4423 else |
| 4397 context_menu_node_.reset(); | 4424 context_menu_node_.reset(); |
| 4398 } | 4425 } |
| OLD | NEW |