1 /* 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 3 * Copyright (C) 2008 Matt Lilek <webkit (at) mattlilek.com> 4 * Copyright (C) 2009 Google Inc. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 16 * its contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "ConsoleMessage.h" 33 34 #include "InspectorFrontend.h" 35 #include "ScriptCallStack.h" 36 #include "ScriptObject.h" 37 38 namespace WebCore { 39 40 ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, const String& m, unsigned li, const String& u, unsigned g) 41 : m_source(s) 42 , m_type(t) 43 , m_level(l) 44 , m_message(m) 45 , m_line(li) 46 , m_url(u) 47 , m_groupLevel(g) 48 , m_repeatCount(1) 49 { 50 } 51 52 ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, ScriptCallStack* callStack, unsigned g, bool storeTrace) 53 : m_source(s) 54 , m_type(t) 55 , m_level(l) 56 #if ENABLE(INSPECTOR) 57 , m_arguments(callStack->at(0).argumentCount()) 58 , m_scriptState(callStack->globalState()) 59 #endif 60 , m_frames(storeTrace ? callStack->size() : 0) 61 , m_groupLevel(g) 62 , m_repeatCount(1) 63 { 64 const ScriptCallFrame& lastCaller = callStack->at(0); 65 m_line = lastCaller.lineNumber(); 66 m_url = lastCaller.sourceURL().string(); 67 68 // FIXME: For now, just store function names as strings. 69 // As ScriptCallStack start storing line number and source URL for all 70 // frames, refactor to use that, as well. 71 if (storeTrace) { 72 for (unsigned i = 0; i < callStack->size(); ++i) 73 m_frames[i] = callStack->at(i).functionName(); 74 } 75 76 #if ENABLE(INSPECTOR) 77 for (unsigned i = 0; i < lastCaller.argumentCount(); ++i) 78 m_arguments[i] = lastCaller.argumentAt(i); 79 #endif 80 } 81 82 #if ENABLE(INSPECTOR) 83 void ConsoleMessage::addToConsole(InspectorFrontend* frontend) 84 { 85 ScriptObject jsonObj = frontend->newScriptObject(); 86 jsonObj.set("source", static_cast<int>(m_source)); 87 jsonObj.set("type", static_cast<int>(m_type)); 88 jsonObj.set("level", static_cast<int>(m_level)); 89 jsonObj.set("line", static_cast<int>(m_line)); 90 jsonObj.set("url", m_url); 91 jsonObj.set("groupLevel", static_cast<int>(m_groupLevel)); 92 jsonObj.set("repeatCount", static_cast<int>(m_repeatCount)); 93 frontend->addConsoleMessage(jsonObj, m_frames, m_scriptState, m_arguments, m_message); 94 } 95 96 void ConsoleMessage::updateRepeatCountInConsole(InspectorFrontend* frontend) 97 { 98 frontend->updateConsoleMessageRepeatCount(m_repeatCount); 99 } 100 #endif // ENABLE(INSPECTOR) 101 102 bool ConsoleMessage::isEqual(ScriptState* state, ConsoleMessage* msg) const 103 { 104 #if ENABLE(INSPECTOR) 105 if (msg->m_arguments.size() != m_arguments.size()) 106 return false; 107 if (!state && msg->m_arguments.size()) 108 return false; 109 110 ASSERT_ARG(state, state || msg->m_arguments.isEmpty()); 111 112 for (size_t i = 0; i < msg->m_arguments.size(); ++i) { 113 if (!m_arguments[i].isEqual(state, msg->m_arguments[i])) 114 return false; 115 } 116 #else 117 UNUSED_PARAM(state); 118 #endif // ENABLE(INSPECTOR) 119 120 size_t frameCount = msg->m_frames.size(); 121 if (frameCount != m_frames.size()) 122 return false; 123 124 for (size_t i = 0; i < frameCount; ++i) { 125 if (m_frames[i] != msg->m_frames[i]) 126 return false; 127 } 128 129 return msg->m_source == m_source 130 && msg->m_type == m_type 131 && msg->m_level == m_level 132 && msg->m_message == m_message 133 && msg->m_line == m_line 134 && msg->m_url == m_url 135 && msg->m_groupLevel == m_groupLevel; 136 } 137 138 } // namespace WebCore 139