Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / renderer / extensions / chrome_extensions_render_frame_observer.cc
1 // 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
5 #include "chrome/renderer/extensions/chrome_extensions_render_frame_observer.h"
6
7 #include "base/strings/string_split.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/common/extensions/chrome_extension_messages.h"
10 #include "content/public/renderer/render_frame.h"
11 #include "extensions/common/stack_frame.h"
12 #include "third_party/WebKit/public/web/WebFrame.h"
13
14 namespace extensions {
15
16 namespace {
17
18 // The delimiter for a stack trace provided by WebKit.
19 const 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).
31 StackTrace 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
75 ChromeExtensionsRenderFrameObserver::ChromeExtensionsRenderFrameObserver(
76     content::RenderFrame* render_frame)
77     : content::RenderFrameObserver(render_frame) {
78 }
79
80 ChromeExtensionsRenderFrameObserver::~ChromeExtensionsRenderFrameObserver() {
81 }
82
83 void ChromeExtensionsRenderFrameObserver::DetailedConsoleMessageAdded(
84     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);
95   Send(new ChromeViewHostMsg_DetailedConsoleMessageAdded(
96       routing_id(), trimmed_message, source, stack_trace, severity_level));
97 }
98
99 void ChromeExtensionsRenderFrameObserver::DidChangeName(
100     const base::string16& name) {
101   Send(new ChromeViewHostMsg_UpdateFrameName(
102       routing_id(),
103       !render_frame()->GetWebFrame()->parent(),
104       base::UTF16ToUTF8(name)));
105 }
106
107 }  // namespace extensions