1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "config.h" 30 #include "core/frame/FrameConsole.h" 31 32 #include "core/dom/Document.h" 33 #include "core/frame/FrameHost.h" 34 #include "core/inspector/ConsoleAPITypes.h" 35 #include "core/inspector/InspectorConsoleInstrumentation.h" 36 #include "core/page/Chrome.h" 37 #include "core/page/ChromeClient.h" 38 #include "core/page/Page.h" 39 #include "wtf/text/StringBuilder.h" 40 41 namespace WebCore { 42 43 namespace { 44 45 int muteCount = 0; 46 47 } 48 49 FrameConsole::FrameConsole(LocalFrame& frame) 50 : m_frame(frame) 51 { 52 } 53 54 void FrameConsole::addMessage(MessageSource source, MessageLevel level, const String& message) 55 { 56 addMessage(source, level, message, String(), 0, 0, nullptr, 0, 0); 57 } 58 59 void FrameConsole::addMessage(MessageSource source, MessageLevel level, const String& message, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack) 60 { 61 addMessage(source, level, message, String(), 0, 0, callStack, 0); 62 } 63 64 void FrameConsole::addMessage(MessageSource source, MessageLevel level, const String& message, const String& url, unsigned lineNumber, unsigned columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack, ScriptState* scriptState, unsigned long requestIdentifier) 65 { 66 if (muteCount) 67 return; 68 69 // FIXME: This should not need to reach for the main-frame. 70 // Inspector code should just take the current frame and know how to walk itself. 71 ExecutionContext* context = m_frame.document(); 72 if (!context) 73 return; 74 75 String messageURL; 76 if (callStack) { 77 messageURL = callStack->at(0).sourceURL(); 78 InspectorInstrumentation::addMessageToConsole(context, source, LogMessageType, level, message, callStack, requestIdentifier); 79 } else { 80 messageURL = url; 81 InspectorInstrumentation::addMessageToConsole(context, source, LogMessageType, level, message, url, lineNumber, columnNumber, scriptState, requestIdentifier); 82 } 83 84 if (source == CSSMessageSource) 85 return; 86 87 String stackTrace; 88 if (callStack && m_frame.chromeClient().shouldReportDetailedMessageForSource(messageURL)) 89 stackTrace = FrameConsole::formatStackTraceString(message, callStack); 90 91 m_frame.chromeClient().addMessageToConsole(&m_frame, source, level, message, lineNumber, messageURL, stackTrace); 92 } 93 94 String FrameConsole::formatStackTraceString(const String& originalMessage, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack) 95 { 96 StringBuilder stackTrace; 97 for (size_t i = 0; i < callStack->size(); ++i) { 98 const ScriptCallFrame& frame = callStack->at(i); 99 stackTrace.append("\n at " + (frame.functionName().length() ? frame.functionName() : "(anonymous function)")); 100 stackTrace.append(" ("); 101 stackTrace.append(frame.sourceURL()); 102 stackTrace.append(':'); 103 stackTrace.append(String::number(frame.lineNumber())); 104 stackTrace.append(':'); 105 stackTrace.append(String::number(frame.columnNumber())); 106 stackTrace.append(')'); 107 } 108 109 return stackTrace.toString(); 110 } 111 112 void FrameConsole::mute() 113 { 114 muteCount++; 115 } 116 117 void FrameConsole::unmute() 118 { 119 ASSERT(muteCount > 0); 120 muteCount--; 121 } 122 123 } // namespace WebCore 124