Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(633)

Side by Side Diff: chrome/renderer/chrome_render_view_observer.cc

Issue 23007021: Report Javascript Runtime Errors to the Error Console (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@dc_ec_feldman
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/chrome_render_view_observer.h" 5 #include "chrome/renderer/chrome_render_view_observer.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/strings/string_split.h"
13 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/common/chrome_constants.h" 15 #include "chrome/common/chrome_constants.h"
15 #include "chrome/common/chrome_switches.h" 16 #include "chrome/common/chrome_switches.h"
16 #include "chrome/common/prerender_messages.h" 17 #include "chrome/common/prerender_messages.h"
17 #include "chrome/common/render_messages.h" 18 #include "chrome/common/render_messages.h"
18 #include "chrome/common/url_constants.h" 19 #include "chrome/common/url_constants.h"
19 #include "chrome/renderer/chrome_render_process_observer.h" 20 #include "chrome/renderer/chrome_render_process_observer.h"
20 #include "chrome/renderer/content_settings_observer.h" 21 #include "chrome/renderer/content_settings_observer.h"
21 #include "chrome/renderer/extensions/dispatcher.h" 22 #include "chrome/renderer/extensions/dispatcher.h"
22 #include "chrome/renderer/external_host_bindings.h" 23 #include "chrome/renderer/external_host_bindings.h"
23 #include "chrome/renderer/frame_sniffer.h" 24 #include "chrome/renderer/frame_sniffer.h"
24 #include "chrome/renderer/prerender/prerender_helper.h" 25 #include "chrome/renderer/prerender/prerender_helper.h"
25 #include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h" 26 #include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h"
26 #include "chrome/renderer/translate/translate_helper.h" 27 #include "chrome/renderer/translate/translate_helper.h"
27 #include "chrome/renderer/webview_color_overlay.h" 28 #include "chrome/renderer/webview_color_overlay.h"
28 #include "content/public/common/bindings_policy.h" 29 #include "content/public/common/bindings_policy.h"
29 #include "content/public/renderer/content_renderer_client.h" 30 #include "content/public/renderer/content_renderer_client.h"
30 #include "content/public/renderer/render_view.h" 31 #include "content/public/renderer/render_view.h"
31 #include "extensions/common/constants.h" 32 #include "extensions/common/constants.h"
33 #include "extensions/common/stack_frame.h"
32 #include "net/base/data_url.h" 34 #include "net/base/data_url.h"
33 #include "skia/ext/image_operations.h" 35 #include "skia/ext/image_operations.h"
34 #include "skia/ext/platform_canvas.h" 36 #include "skia/ext/platform_canvas.h"
35 #include "third_party/WebKit/public/platform/WebCString.h" 37 #include "third_party/WebKit/public/platform/WebCString.h"
36 #include "third_party/WebKit/public/platform/WebRect.h" 38 #include "third_party/WebKit/public/platform/WebRect.h"
37 #include "third_party/WebKit/public/platform/WebSize.h" 39 #include "third_party/WebKit/public/platform/WebSize.h"
38 #include "third_party/WebKit/public/platform/WebString.h" 40 #include "third_party/WebKit/public/platform/WebString.h"
39 #include "third_party/WebKit/public/platform/WebURLRequest.h" 41 #include "third_party/WebKit/public/platform/WebURLRequest.h"
40 #include "third_party/WebKit/public/platform/WebVector.h" 42 #include "third_party/WebKit/public/platform/WebVector.h"
41 #include "third_party/WebKit/public/web/WebAccessibilityObject.h" 43 #include "third_party/WebKit/public/web/WebAccessibilityObject.h"
42 #include "third_party/WebKit/public/web/WebDataSource.h" 44 #include "third_party/WebKit/public/web/WebDataSource.h"
43 #include "third_party/WebKit/public/web/WebDocument.h" 45 #include "third_party/WebKit/public/web/WebDocument.h"
44 #include "third_party/WebKit/public/web/WebElement.h" 46 #include "third_party/WebKit/public/web/WebElement.h"
45 #include "third_party/WebKit/public/web/WebFrame.h" 47 #include "third_party/WebKit/public/web/WebFrame.h"
46 #include "third_party/WebKit/public/web/WebInputEvent.h" 48 #include "third_party/WebKit/public/web/WebInputEvent.h"
47 #include "third_party/WebKit/public/web/WebNode.h" 49 #include "third_party/WebKit/public/web/WebNode.h"
48 #include "third_party/WebKit/public/web/WebNodeList.h" 50 #include "third_party/WebKit/public/web/WebNodeList.h"
49 #include "third_party/WebKit/public/web/WebView.h" 51 #include "third_party/WebKit/public/web/WebView.h"
50 #include "ui/base/ui_base_switches_util.h" 52 #include "ui/base/ui_base_switches_util.h"
51 #include "ui/gfx/favicon_size.h" 53 #include "ui/gfx/favicon_size.h"
52 #include "ui/gfx/size.h" 54 #include "ui/gfx/size.h"
53 #include "ui/gfx/size_f.h" 55 #include "ui/gfx/size_f.h"
54 #include "ui/gfx/skbitmap_operations.h" 56 #include "ui/gfx/skbitmap_operations.h"
55 #include "v8/include/v8-testing.h" 57 #include "v8/include/v8-testing.h"
56 #include "webkit/glue/webkit_glue.h" 58 #include "webkit/glue/webkit_glue.h"
57 59
60 using base::string16;
61 using extensions::APIPermission;
58 using WebKit::WebAccessibilityObject; 62 using WebKit::WebAccessibilityObject;
59 using WebKit::WebCString; 63 using WebKit::WebCString;
60 using WebKit::WebDataSource; 64 using WebKit::WebDataSource;
61 using WebKit::WebDocument; 65 using WebKit::WebDocument;
62 using WebKit::WebElement; 66 using WebKit::WebElement;
63 using WebKit::WebFrame; 67 using WebKit::WebFrame;
64 using WebKit::WebGestureEvent; 68 using WebKit::WebGestureEvent;
65 using WebKit::WebIconURL; 69 using WebKit::WebIconURL;
66 using WebKit::WebNode; 70 using WebKit::WebNode;
67 using WebKit::WebNodeList; 71 using WebKit::WebNodeList;
68 using WebKit::WebRect; 72 using WebKit::WebRect;
69 using WebKit::WebSecurityOrigin; 73 using WebKit::WebSecurityOrigin;
70 using WebKit::WebSize; 74 using WebKit::WebSize;
71 using WebKit::WebString; 75 using WebKit::WebString;
72 using WebKit::WebTouchEvent; 76 using WebKit::WebTouchEvent;
73 using WebKit::WebURL; 77 using WebKit::WebURL;
74 using WebKit::WebURLRequest; 78 using WebKit::WebURLRequest;
75 using WebKit::WebView; 79 using WebKit::WebView;
76 using WebKit::WebVector; 80 using WebKit::WebVector;
77 using WebKit::WebWindowFeatures; 81 using WebKit::WebWindowFeatures;
78 using extensions::APIPermission;
79 82
80 // Delay in milliseconds that we'll wait before capturing the page contents 83 // Delay in milliseconds that we'll wait before capturing the page contents
81 // and thumbnail. 84 // and thumbnail.
82 static const int kDelayForCaptureMs = 500; 85 static const int kDelayForCaptureMs = 500;
83 86
84 // Typically, we capture the page data once the page is loaded. 87 // Typically, we capture the page data once the page is loaded.
85 // Sometimes, the page never finishes to load, preventing the page capture 88 // Sometimes, the page never finishes to load, preventing the page capture
86 // To workaround this problem, we always perform a capture after the following 89 // To workaround this problem, we always perform a capture after the following
87 // delay. 90 // delay.
88 static const int kDelayForForcedCaptureMs = 6000; 91 static const int kDelayForForcedCaptureMs = 6000;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 static const char kGoogleDotCom[] = "google.com"; 162 static const char kGoogleDotCom[] = "google.com";
160 163
161 static bool isHostInDomain(const std::string& host, const std::string& domain) { 164 static bool isHostInDomain(const std::string& host, const std::string& domain) {
162 return (EndsWith(host, domain, false) && 165 return (EndsWith(host, domain, false) &&
163 (host.length() == domain.length() || 166 (host.length() == domain.length() ||
164 (host.length() > domain.length() && 167 (host.length() > domain.length() &&
165 host[host.length() - domain.length() - 1] == '.'))); 168 host[host.length() - domain.length() - 1] == '.')));
166 } 169 }
167 170
168 namespace { 171 namespace {
172
169 GURL StripRef(const GURL& url) { 173 GURL StripRef(const GURL& url) {
170 GURL::Replacements replacements; 174 GURL::Replacements replacements;
171 replacements.ClearRef(); 175 replacements.ClearRef();
172 return url.ReplaceComponents(replacements); 176 return url.ReplaceComponents(replacements);
173 } 177 }
174 178
175 // If the source image is null or occupies less area than 179 // If the source image is null or occupies less area than
176 // |thumbnail_min_area_pixels|, we return the image unmodified. Otherwise, we 180 // |thumbnail_min_area_pixels|, we return the image unmodified. Otherwise, we
177 // scale down the image so that the width and height do not exceed 181 // scale down the image so that the width and height do not exceed
178 // |thumbnail_max_size_pixels|, preserving the original aspect ratio. 182 // |thumbnail_max_size_pixels|, preserving the original aspect ratio.
179 static SkBitmap Downscale(WebKit::WebImage image, 183 SkBitmap Downscale(WebKit::WebImage image,
180 int thumbnail_min_area_pixels, 184 int thumbnail_min_area_pixels,
181 gfx::Size thumbnail_max_size_pixels) { 185 gfx::Size thumbnail_max_size_pixels) {
182 if (image.isNull()) 186 if (image.isNull())
183 return SkBitmap(); 187 return SkBitmap();
184 188
185 gfx::Size image_size = image.size(); 189 gfx::Size image_size = image.size();
186 190
187 if (image_size.GetArea() < thumbnail_min_area_pixels) 191 if (image_size.GetArea() < thumbnail_min_area_pixels)
188 return image.getSkBitmap(); 192 return image.getSkBitmap();
189 193
190 if (image_size.width() <= thumbnail_max_size_pixels.width() && 194 if (image_size.width() <= thumbnail_max_size_pixels.width() &&
191 image_size.height() <= thumbnail_max_size_pixels.height()) 195 image_size.height() <= thumbnail_max_size_pixels.height())
192 return image.getSkBitmap(); 196 return image.getSkBitmap();
193 197
194 gfx::SizeF scaled_size = image_size; 198 gfx::SizeF scaled_size = image_size;
195 199
196 if (scaled_size.width() > thumbnail_max_size_pixels.width()) { 200 if (scaled_size.width() > thumbnail_max_size_pixels.width()) {
197 scaled_size.Scale(thumbnail_max_size_pixels.width() / scaled_size.width()); 201 scaled_size.Scale(thumbnail_max_size_pixels.width() / scaled_size.width());
198 } 202 }
199 203
200 if (scaled_size.height() > thumbnail_max_size_pixels.height()) { 204 if (scaled_size.height() > thumbnail_max_size_pixels.height()) {
201 scaled_size.Scale( 205 scaled_size.Scale(
202 thumbnail_max_size_pixels.height() / scaled_size.height()); 206 thumbnail_max_size_pixels.height() / scaled_size.height());
203 } 207 }
204 208
205 return skia::ImageOperations::Resize(image.getSkBitmap(), 209 return skia::ImageOperations::Resize(image.getSkBitmap(),
206 skia::ImageOperations::RESIZE_GOOD, 210 skia::ImageOperations::RESIZE_GOOD,
207 static_cast<int>(scaled_size.width()), 211 static_cast<int>(scaled_size.width()),
208 static_cast<int>(scaled_size.height())); 212 static_cast<int>(scaled_size.height()));
209 } 213 }
214
215 // The delimiter for a stack trace provided by WebKit.
216 const char kStackFrameDelimiter[] = "\n at ";
217
218 // Get a stack trace from a WebKit console message.
219 // There are three possible scenarios:
220 // 1. WebKit gives us a stack trace in |stack_trace|.
221 // 2. The stack trace is embedded in the error |message| by an internal
222 // script. This will be more useful than |stack_trace|, since |stack_trace|
223 // will include the internal bindings trace, instead of a developer's code.
224 // 3. No stack trace is included. In this case, we should mock one up from
225 // the given line number and source.
226 // |message| will be populated with the error message only (i.e., will not
227 // include any stack trace).
228 extensions::StackTrace GetStackTraceFromMessage(string16* message,
229 const string16& source,
230 const string16& stack_trace,
231 int32 line_number) {
232 extensions::StackTrace result;
233 std::vector<base::string16> pieces;
234 size_t index = 0;
235
236 if (message->find(base::UTF8ToUTF16(kStackFrameDelimiter)) !=
237 string16::npos) {
238 base::SplitStringUsingSubstr(*message,
239 base::UTF8ToUTF16(kStackFrameDelimiter),
240 &pieces);
241 *message = pieces[0];
242 index = 1;
243 } else if (!stack_trace.empty()) {
244 base::SplitStringUsingSubstr(stack_trace,
245 base::UTF8ToUTF16(kStackFrameDelimiter),
246 &pieces);
247 }
248
249 // If we got a stack trace, parse each frame from the text.
250 if (index < pieces.size()) {
251 for (; index < pieces.size(); ++index) {
252 scoped_ptr<extensions::StackFrame> frame =
253 extensions::StackFrame::CreateFromText(pieces[index]);
254 if (frame.get())
255 result.push_back(*frame);
256 }
257 }
258
259 if (result.empty()) { // If we don't have a stack trace, mock one up.
260 result.push_back(
261 extensions::StackFrame(line_number,
262 1u, // column number
263 source,
264 EmptyString16() /* no function name */ ));
265 }
266
267 return result;
268 }
269
210 } // namespace 270 } // namespace
211 271
212 ChromeRenderViewObserver::ChromeRenderViewObserver( 272 ChromeRenderViewObserver::ChromeRenderViewObserver(
213 content::RenderView* render_view, 273 content::RenderView* render_view,
214 ContentSettingsObserver* content_settings, 274 ContentSettingsObserver* content_settings,
215 ChromeRenderProcessObserver* chrome_render_process_observer, 275 ChromeRenderProcessObserver* chrome_render_process_observer,
216 extensions::Dispatcher* extension_dispatcher) 276 extensions::Dispatcher* extension_dispatcher)
217 : content::RenderViewObserver(render_view), 277 : content::RenderViewObserver(render_view),
218 chrome_render_process_observer_(chrome_render_process_observer), 278 chrome_render_process_observer_(chrome_render_process_observer),
219 extension_dispatcher_(extension_dispatcher), 279 extension_dispatcher_(extension_dispatcher),
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 return; 820 return;
761 821
762 WebKit::WebTextInputType text_input_type = 822 WebKit::WebTextInputType text_input_type =
763 render_view()->GetWebView()->textInputInfo().type; 823 render_view()->GetWebView()->textInputInfo().type;
764 824
765 render_view()->Send(new ChromeViewHostMsg_FocusedNodeTouched( 825 render_view()->Send(new ChromeViewHostMsg_FocusedNodeTouched(
766 routing_id(), 826 routing_id(),
767 text_input_type != WebKit::WebTextInputTypeNone)); 827 text_input_type != WebKit::WebTextInputTypeNone));
768 } 828 }
769 829
830 void ChromeRenderViewObserver::DetailedConsoleMessageAdded(
831 const base::string16& message,
832 const base::string16& source,
833 const base::string16& stack_trace_string,
834 int32 line_number,
835 int32 severity_level) {
836 string16 trimmed_message = message;
837 extensions::StackTrace stack_trace = GetStackTraceFromMessage(
838 &trimmed_message,
839 source,
840 stack_trace_string,
841 line_number);
842 Send(new ChromeViewHostMsg_DetailedConsoleMessageAdded(routing_id(),
843 trimmed_message,
844 source,
845 stack_trace,
846 severity_level));
847 }
848
770 void ChromeRenderViewObserver::CapturePageInfoLater(int page_id, 849 void ChromeRenderViewObserver::CapturePageInfoLater(int page_id,
771 bool preliminary_capture, 850 bool preliminary_capture,
772 base::TimeDelta delay) { 851 base::TimeDelta delay) {
773 capture_timer_.Start( 852 capture_timer_.Start(
774 FROM_HERE, 853 FROM_HERE,
775 delay, 854 delay,
776 base::Bind(&ChromeRenderViewObserver::CapturePageInfo, 855 base::Bind(&ChromeRenderViewObserver::CapturePageInfo,
777 base::Unretained(this), 856 base::Unretained(this),
778 page_id, 857 page_id,
779 preliminary_capture)); 858 preliminary_capture));
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 WebElement element = node.to<WebElement>(); 1009 WebElement element = node.to<WebElement>();
931 if (!element.hasTagName(tag_name)) 1010 if (!element.hasTagName(tag_name))
932 continue; 1011 continue;
933 WebString value = element.getAttribute(attribute_name); 1012 WebString value = element.getAttribute(attribute_name);
934 if (value.isNull() || !LowerCaseEqualsASCII(value, "refresh")) 1013 if (value.isNull() || !LowerCaseEqualsASCII(value, "refresh"))
935 continue; 1014 continue;
936 return true; 1015 return true;
937 } 1016 }
938 return false; 1017 return false;
939 } 1018 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698