blob: 7877bb6637847fab464aa162fed6ad38f1195d17 [file] [log] [blame]
[email protected]8ff54242014-06-07 08:19:451// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]9a1314a2014-08-18 19:27:395#include "extensions/renderer/extensions_render_frame_observer.h"
[email protected]8ff54242014-06-07 08:19:456
7#include "base/strings/string_split.h"
8#include "base/strings/utf_string_conversions.h"
[email protected]bd35d3a2014-06-22 01:12:519#include "content/public/renderer/render_frame.h"
[email protected]9a1314a2014-08-18 19:27:3910#include "extensions/common/extension_messages.h"
[email protected]8ff54242014-06-07 08:19:4511#include "extensions/common/stack_frame.h"
[email protected]bd35d3a2014-06-22 01:12:5112#include "third_party/WebKit/public/web/WebFrame.h"
[email protected]8ff54242014-06-07 08:19:4513
14namespace extensions {
15
16namespace {
17
18// The delimiter for a stack trace provided by WebKit.
19const char kStackFrameDelimiter[] = "\n at ";
20
21// Get a stack trace from a WebKit console message.
22// There are three possible scenarios:
23// 1. WebKit gives us a stack trace in |stack_trace|.
24// 2. The stack trace is embedded in the error |message| by an internal
25// script. This will be more useful than |stack_trace|, since |stack_trace|
26// will include the internal bindings trace, instead of a developer's code.
27// 3. No stack trace is included. In this case, we should mock one up from
28// the given line number and source.
29// |message| will be populated with the error message only (i.e., will not
30// include any stack trace).
31StackTrace GetStackTraceFromMessage(
32 base::string16* message,
33 const base::string16& source,
34 const base::string16& stack_trace,
35 int32 line_number) {
36 StackTrace result;
37 std::vector<base::string16> pieces;
38 size_t index = 0;
39
40 if (message->find(base::UTF8ToUTF16(kStackFrameDelimiter)) !=
41 base::string16::npos) {
42 base::SplitStringUsingSubstr(*message,
43 base::UTF8ToUTF16(kStackFrameDelimiter),
44 &pieces);
45 *message = pieces[0];
46 index = 1;
47 } else if (!stack_trace.empty()) {
48 base::SplitStringUsingSubstr(stack_trace,
49 base::UTF8ToUTF16(kStackFrameDelimiter),
50 &pieces);
51 }
52
53 // If we got a stack trace, parse each frame from the text.
54 if (index < pieces.size()) {
55 for (; index < pieces.size(); ++index) {
56 scoped_ptr<StackFrame> frame = StackFrame::CreateFromText(pieces[index]);
57 if (frame.get())
58 result.push_back(*frame);
59 }
60 }
61
62 if (result.empty()) { // If we don't have a stack trace, mock one up.
63 result.push_back(
64 StackFrame(line_number,
65 1u, // column number
66 source,
67 base::string16() /* no function name */ ));
68 }
69
70 return result;
71}
72
73} // namespace
74
[email protected]9a1314a2014-08-18 19:27:3975ExtensionsRenderFrameObserver::ExtensionsRenderFrameObserver(
[email protected]8ff54242014-06-07 08:19:4576 content::RenderFrame* render_frame)
77 : content::RenderFrameObserver(render_frame) {
78}
79
[email protected]9a1314a2014-08-18 19:27:3980ExtensionsRenderFrameObserver::~ExtensionsRenderFrameObserver() {
[email protected]8ff54242014-06-07 08:19:4581}
82
[email protected]9a1314a2014-08-18 19:27:3983void ExtensionsRenderFrameObserver::DetailedConsoleMessageAdded(
[email protected]8ff54242014-06-07 08:19:4584 const base::string16& message,
85 const base::string16& source,
86 const base::string16& stack_trace_string,
87 int32 line_number,
88 int32 severity_level) {
89 base::string16 trimmed_message = message;
90 StackTrace stack_trace = GetStackTraceFromMessage(
91 &trimmed_message,
92 source,
93 stack_trace_string,
94 line_number);
[email protected]9a1314a2014-08-18 19:27:3995 Send(new ExtensionHostMsg_DetailedConsoleMessageAdded(
[email protected]8ff54242014-06-07 08:19:4596 routing_id(), trimmed_message, source, stack_trace, severity_level));
97}
98
[email protected]9a1314a2014-08-18 19:27:3999void ExtensionsRenderFrameObserver::DidChangeName(
[email protected]bd35d3a2014-06-22 01:12:51100 const base::string16& name) {
[email protected]9a1314a2014-08-18 19:27:39101 Send(new ExtensionHostMsg_FrameNameChanged(
[email protected]bd35d3a2014-06-22 01:12:51102 routing_id(),
103 !render_frame()->GetWebFrame()->parent(),
104 base::UTF16ToUTF8(name)));
105}
106
[email protected]8ff54242014-06-07 08:19:45107} // namespace extensions