Chromium Code Reviews| Index: Source/core/inspector/InspectorConsoleAgent.cpp |
| diff --git a/Source/core/inspector/InspectorConsoleAgent.cpp b/Source/core/inspector/InspectorConsoleAgent.cpp |
| index ef7ac04912188efa2247f3797f29803ea625bc4c..ca102934ce08b548d0c85b2dcc510c78a351b439 100644 |
| --- a/Source/core/inspector/InspectorConsoleAgent.cpp |
| +++ b/Source/core/inspector/InspectorConsoleAgent.cpp |
| @@ -29,17 +29,21 @@ |
| #include "bindings/core/v8/ScriptCallStackFactory.h" |
| #include "bindings/core/v8/ScriptController.h" |
| #include "bindings/core/v8/ScriptProfiler.h" |
| +#include "core/frame/FrameConsole.h" |
| #include "core/frame/LocalFrame.h" |
| #include "core/frame/UseCounter.h" |
| #include "core/inspector/ConsoleMessage.h" |
| +#include "core/inspector/ConsoleMessageStorage.h" |
| +#include "core/inspector/IdentifiersFactory.h" |
| +#include "core/inspector/InjectedScript.h" |
| #include "core/inspector/InjectedScriptHost.h" |
| #include "core/inspector/InjectedScriptManager.h" |
| -#include "core/inspector/InspectorConsoleMessage.h" |
| #include "core/inspector/InspectorState.h" |
| #include "core/inspector/InspectorTimelineAgent.h" |
| #include "core/inspector/InspectorTracingAgent.h" |
| #include "core/inspector/InstrumentingAgents.h" |
| #include "core/inspector/ScriptArguments.h" |
| +#include "core/inspector/ScriptAsyncCallStack.h" |
| #include "core/inspector/ScriptCallFrame.h" |
| #include "core/inspector/ScriptCallStack.h" |
| #include "core/loader/DocumentLoader.h" |
| @@ -55,9 +59,6 @@ |
| namespace blink { |
| -static const unsigned maximumConsoleMessages = 1000; |
| -static const int expireConsoleMessagesStep = 100; |
| - |
| namespace ConsoleAgentState { |
| static const char monitoringXHR[] = "monitoringXHR"; |
| static const char consoleMessagesEnabled[] = "consoleMessagesEnabled"; |
| @@ -72,7 +73,6 @@ InspectorConsoleAgent::InspectorConsoleAgent(InspectorTimelineAgent* timelineAge |
| , m_tracingAgent(tracingAgent) |
| , m_injectedScriptManager(injectedScriptManager) |
| , m_frontend(0) |
| - , m_expiredConsoleMessageCount(0) |
| , m_enabled(false) |
| { |
| } |
| @@ -108,15 +108,17 @@ void InspectorConsoleAgent::enable(ErrorString*) |
| m_state->setBoolean(ConsoleAgentState::consoleMessagesEnabled, true); |
| - if (m_expiredConsoleMessageCount) { |
| - InspectorConsoleMessage expiredMessage(OtherMessageSource, LogMessageType, WarningMessageLevel, String::format("%d console messages are not shown.", m_expiredConsoleMessageCount)); |
| - expiredMessage.setTimestamp(0); |
| - expiredMessage.addToFrontend(m_frontend, m_injectedScriptManager, false); |
| + ConsoleMessageStorage* storage = messageStorage(); |
| + if (storage) { |
| + if (storage->expiredCount()) { |
| + RefPtr<ConsoleMessage> expiredMessage = ConsoleMessage::create(OtherMessageSource, WarningMessageLevel, String::format("%d console messages are not shown.", storage->expiredCount())); |
| + expiredMessage->setTimestamp(0); |
| + sendConsoleMessageToFrontend(expiredMessage, false); |
| + } |
| + size_t messageCount = storage->size(); |
| + for (size_t i = 0; i < messageCount; ++i) |
| + sendConsoleMessageToFrontend(storage->at(i), false); |
| } |
| - |
| - size_t messageCount = m_consoleMessages.size(); |
| - for (size_t i = 0; i < messageCount; ++i) |
| - m_consoleMessages[i]->addToFrontend(m_frontend, m_injectedScriptManager, false); |
| } |
| void InspectorConsoleAgent::disable(ErrorString*) |
| @@ -132,8 +134,9 @@ void InspectorConsoleAgent::disable(ErrorString*) |
| void InspectorConsoleAgent::clearMessages(ErrorString*) |
| { |
| - m_consoleMessages.clear(); |
| - m_expiredConsoleMessageCount = 0; |
| + ConsoleMessageStorage* storage = messageStorage(); |
| + if (storage) |
| + storage->clear(); |
| m_injectedScriptManager->releaseObjectGroup("console"); |
| if (m_frontend && m_enabled) |
| m_frontend->messagesCleared(); |
| @@ -168,24 +171,21 @@ void InspectorConsoleAgent::clearFrontend() |
| disable(&errorString); |
| } |
| -void InspectorConsoleAgent::addMessageToConsole(ConsoleMessage* consoleMessage) |
| +void InspectorConsoleAgent::addMessageToConsole(PassRefPtr<ConsoleMessage> consoleMessage) |
| { |
| - InspectorConsoleMessage* message; |
| - if (consoleMessage->callStack()) { |
| - message = new InspectorConsoleMessage(consoleMessage->source(), LogMessageType, consoleMessage->level(), consoleMessage->message(), consoleMessage->callStack(), consoleMessage->requestIdentifier()); |
| - } else { |
| - bool shouldGenerateCallStack = m_frontend; |
| - message = new InspectorConsoleMessage(shouldGenerateCallStack, consoleMessage->source(), LogMessageType, consoleMessage->level(), consoleMessage->message(), consoleMessage->url(), consoleMessage->lineNumber(), consoleMessage->columnNumber(), consoleMessage->scriptState(), consoleMessage->requestIdentifier()); |
| - } |
| - message->setWorkerGlobalScopeProxy(consoleMessage->workerId()); |
| - addConsoleMessage(adoptPtr(message)); |
| + if (m_frontend && m_enabled) |
| + sendConsoleMessageToFrontend(consoleMessage, true); |
| } |
| void InspectorConsoleAgent::adoptWorkerConsoleMessages(WorkerGlobalScopeProxy* proxy) |
| { |
| - for (size_t i = 0; i < m_consoleMessages.size(); i++) { |
| - if (m_consoleMessages[i]->workerGlobalScopeProxy() == proxy) |
| - m_consoleMessages[i]->setWorkerGlobalScopeProxy(nullptr); |
| + ConsoleMessageStorage* storage = messageStorage(); |
| + if (storage) { |
| + size_t messageCount = storage->size(); |
| + for (size_t i = 0; i < messageCount; i++) { |
| + if (storage->at(i)->workerId() == proxy) |
| + storage->at(i)->setWorkerId(nullptr); |
| + } |
| } |
| } |
| @@ -196,15 +196,22 @@ void InspectorConsoleAgent::addConsoleAPIMessageToConsole(MessageType type, Mess |
| clearMessages(&error); |
| } |
| - addConsoleMessage(adoptPtr(new InspectorConsoleMessage(ConsoleAPIMessageSource, type, level, message, arguments, scriptState, requestIdentifier))); |
| + RefPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(ConsoleAPIMessageSource, level, message); |
|
vsevik
2014/08/14 08:06:22
This code belongs to ConsoleBase and we'd better m
kozyatinskiy1
2014/08/20 13:44:18
Done.
|
| + consoleMessage->setType(type); |
| + consoleMessage->setScriptState(scriptState); |
| + consoleMessage->setScriptArguments(arguments); |
| + consoleMessage->setRequestIdentifier(requestIdentifier); |
| + |
| + storeConsoleMessage(consoleMessage); |
| + addMessageToConsole(consoleMessage.release()); |
| } |
| Vector<unsigned> InspectorConsoleAgent::consoleMessageArgumentCounts() |
|
vsevik
2014/08/14 08:06:22
This method is only used for tests. There is no re
kozyatinskiy1
2014/08/20 13:44:18
Done.
|
| { |
| - Vector<unsigned> result(m_consoleMessages.size()); |
| - for (size_t i = 0; i < m_consoleMessages.size(); i++) |
| - result[i] = m_consoleMessages[i]->argumentCount(); |
| - return result; |
| + ConsoleMessageStorage* storage = messageStorage(); |
| + if (storage) |
| + return storage->argumentCounts(); |
| + return Vector<unsigned>(); |
| } |
| void InspectorConsoleAgent::consoleTime(ExecutionContext*, const String& title) |
| @@ -276,9 +283,10 @@ void InspectorConsoleAgent::consoleCount(ScriptState* scriptState, PassRefPtrWil |
| void InspectorConsoleAgent::frameWindowDiscarded(LocalDOMWindow* window) |
| { |
| - size_t messageCount = m_consoleMessages.size(); |
| - for (size_t i = 0; i < messageCount; ++i) |
| - m_consoleMessages[i]->windowCleared(window); |
| + ConsoleMessageStorage* storage = messageStorage(); |
| + if (storage) |
| + storage->windowCleared(window); |
|
vsevik
2014/08/14 08:06:22
This is a basic storage functionality and should d
kozyatinskiy1
2014/08/20 13:44:18
Done.
|
| + |
| m_injectedScriptManager->discardInjectedScriptsFor(window); |
| } |
| @@ -295,11 +303,12 @@ void InspectorConsoleAgent::didFinishXHRLoading(XMLHttpRequest*, ThreadableLoade |
| String message = "XHR finished loading: " + method + " \"" + url + "\"."; |
| RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(NetworkMessageSource, DebugMessageLevel, message, sendURL, sendLineNumber); |
| consoleMessage->setRequestIdentifier(requestIdentifier); |
| - addMessageToConsole(consoleMessage.get()); |
| + storeConsoleMessage(consoleMessage); |
|
vsevik
2014/08/14 08:06:22
These two methods are always called together and t
kozyatinskiy1
2014/08/20 13:44:18
Done.
|
| + addMessageToConsole(consoleMessage.release()); |
|
vsevik
2014/08/14 08:06:22
Actually since this storeConsoleMessage approach i
kozyatinskiy1
2014/08/20 13:44:18
The tests are not broken.
|
| } |
| } |
| -void InspectorConsoleAgent::didReceiveResourceResponse(LocalFrame*, unsigned long requestIdentifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader) |
| +void InspectorConsoleAgent::didReceiveResourceResponse(LocalFrame* frame, unsigned long requestIdentifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader) |
|
vsevik
2014/08/14 08:06:22
frame is not used
kozyatinskiy1
2014/08/20 13:44:18
Done.
|
| { |
| if (!loader) |
| return; |
| @@ -307,7 +316,8 @@ void InspectorConsoleAgent::didReceiveResourceResponse(LocalFrame*, unsigned lon |
| String message = "Failed to load resource: the server responded with a status of " + String::number(response.httpStatusCode()) + " (" + response.httpStatusText() + ')'; |
| RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(NetworkMessageSource, ErrorMessageLevel, message, response.url().string()); |
| consoleMessage->setRequestIdentifier(requestIdentifier); |
| - addMessageToConsole(consoleMessage.get()); |
| + storeConsoleMessage(consoleMessage); |
| + addMessageToConsole(consoleMessage.release()); |
| } |
| } |
| @@ -323,7 +333,8 @@ void InspectorConsoleAgent::didFailLoading(unsigned long requestIdentifier, cons |
| } |
| RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(NetworkMessageSource, ErrorMessageLevel, message.toString(), error.failingURL()); |
| consoleMessage->setRequestIdentifier(requestIdentifier); |
| - addMessageToConsole(consoleMessage.get()); |
| + storeConsoleMessage(consoleMessage); |
| + addMessageToConsole(consoleMessage.release()); |
| } |
| void InspectorConsoleAgent::setMonitoringXHREnabled(ErrorString*, bool enabled) |
| @@ -331,19 +342,116 @@ void InspectorConsoleAgent::setMonitoringXHREnabled(ErrorString*, bool enabled) |
| m_state->setBoolean(ConsoleAgentState::monitoringXHR, enabled); |
| } |
| -void InspectorConsoleAgent::addConsoleMessage(PassOwnPtr<InspectorConsoleMessage> consoleMessage) |
| +void InspectorConsoleAgent::storeConsoleMessage(PassRefPtr<ConsoleMessage> consoleMessage) |
| { |
| - ASSERT_ARG(consoleMessage, consoleMessage); |
| + ConsoleMessageStorage* storage = messageStorage(); |
| + if (storage) |
| + storage->addMessage(consoleMessage); |
| +} |
| - if (m_frontend && m_enabled) |
| - consoleMessage->addToFrontend(m_frontend, m_injectedScriptManager, true); |
| +static TypeBuilder::Console::ConsoleMessage::Source::Enum messageSourceValue(MessageSource source) |
| +{ |
| + switch (source) { |
| + case XMLMessageSource: return TypeBuilder::Console::ConsoleMessage::Source::Xml; |
| + case JSMessageSource: return TypeBuilder::Console::ConsoleMessage::Source::Javascript; |
| + case NetworkMessageSource: return TypeBuilder::Console::ConsoleMessage::Source::Network; |
| + case ConsoleAPIMessageSource: return TypeBuilder::Console::ConsoleMessage::Source::Console_api; |
| + case StorageMessageSource: return TypeBuilder::Console::ConsoleMessage::Source::Storage; |
| + case AppCacheMessageSource: return TypeBuilder::Console::ConsoleMessage::Source::Appcache; |
| + case RenderingMessageSource: return TypeBuilder::Console::ConsoleMessage::Source::Rendering; |
| + case CSSMessageSource: return TypeBuilder::Console::ConsoleMessage::Source::Css; |
| + case SecurityMessageSource: return TypeBuilder::Console::ConsoleMessage::Source::Security; |
| + case OtherMessageSource: return TypeBuilder::Console::ConsoleMessage::Source::Other; |
| + case DeprecationMessageSource: return TypeBuilder::Console::ConsoleMessage::Source::Deprecation; |
| + } |
| + return TypeBuilder::Console::ConsoleMessage::Source::Other; |
| +} |
| - m_consoleMessages.append(consoleMessage); |
| +static TypeBuilder::Console::ConsoleMessage::Type::Enum messageTypeValue(MessageType type) |
| +{ |
| + switch (type) { |
| + case LogMessageType: return TypeBuilder::Console::ConsoleMessage::Type::Log; |
| + case ClearMessageType: return TypeBuilder::Console::ConsoleMessage::Type::Clear; |
| + case DirMessageType: return TypeBuilder::Console::ConsoleMessage::Type::Dir; |
| + case DirXMLMessageType: return TypeBuilder::Console::ConsoleMessage::Type::Dirxml; |
| + case TableMessageType: return TypeBuilder::Console::ConsoleMessage::Type::Table; |
| + case TraceMessageType: return TypeBuilder::Console::ConsoleMessage::Type::Trace; |
| + case StartGroupMessageType: return TypeBuilder::Console::ConsoleMessage::Type::StartGroup; |
| + case StartGroupCollapsedMessageType: return TypeBuilder::Console::ConsoleMessage::Type::StartGroupCollapsed; |
| + case EndGroupMessageType: return TypeBuilder::Console::ConsoleMessage::Type::EndGroup; |
| + case AssertMessageType: return TypeBuilder::Console::ConsoleMessage::Type::Assert; |
| + } |
| + return TypeBuilder::Console::ConsoleMessage::Type::Log; |
| +} |
| + |
| +static TypeBuilder::Console::ConsoleMessage::Level::Enum messageLevelValue(MessageLevel level) |
| +{ |
| + switch (level) { |
| + case DebugMessageLevel: return TypeBuilder::Console::ConsoleMessage::Level::Debug; |
| + case LogMessageLevel: return TypeBuilder::Console::ConsoleMessage::Level::Log; |
| + case WarningMessageLevel: return TypeBuilder::Console::ConsoleMessage::Level::Warning; |
| + case ErrorMessageLevel: return TypeBuilder::Console::ConsoleMessage::Level::Error; |
| + case InfoMessageLevel: return TypeBuilder::Console::ConsoleMessage::Level::Info; |
| + } |
| + return TypeBuilder::Console::ConsoleMessage::Level::Log; |
| +} |
| + |
| +void InspectorConsoleAgent::sendConsoleMessageToFrontend(PassRefPtr<ConsoleMessage> consoleMessage, bool generatePreview) |
| +{ |
| + if (consoleMessage->workerId()) |
| + return; |
| - if (!m_frontend && m_consoleMessages.size() >= maximumConsoleMessages) { |
| - m_expiredConsoleMessageCount += expireConsoleMessagesStep; |
| - m_consoleMessages.remove(0, expireConsoleMessagesStep); |
| + RefPtr<TypeBuilder::Console::ConsoleMessage> jsonObj = TypeBuilder::Console::ConsoleMessage::create() |
| + .setSource(messageSourceValue(consoleMessage->source())) |
| + .setLevel(messageLevelValue(consoleMessage->level())) |
| + .setText(consoleMessage->message()) |
| + .setTimestamp(consoleMessage->timestamp()); |
| + // FIXME: only send out type for ConsoleAPI source messages. |
| + jsonObj->setType(messageTypeValue(consoleMessage->type())); |
| + jsonObj->setLine(static_cast<int>(consoleMessage->lineNumber())); |
| + jsonObj->setColumn(static_cast<int>(consoleMessage->columnNumber())); |
| + jsonObj->setUrl(consoleMessage->url()); |
| + ScriptState* scriptState = consoleMessage->scriptState(); |
| + if (scriptState) |
| + jsonObj->setExecutionContextId(m_injectedScriptManager->injectedScriptIdFor(scriptState)); |
| + if (consoleMessage->source() == NetworkMessageSource && consoleMessage->requestIdentifier()) |
| + jsonObj->setNetworkRequestId(IdentifiersFactory::requestId(consoleMessage->requestIdentifier())); |
| + |
| + RefPtr<ScriptArguments> arguments = consoleMessage->scriptArguments(); |
| + if (arguments && arguments->argumentCount()) { |
| + InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(arguments->scriptState()); |
| + if (!injectedScript.isEmpty()) { |
| + RefPtr<TypeBuilder::Array<TypeBuilder::Runtime::RemoteObject> > jsonArgs = TypeBuilder::Array<TypeBuilder::Runtime::RemoteObject>::create(); |
| + if (consoleMessage->type() == TableMessageType && generatePreview && arguments->argumentCount()) { |
| + ScriptValue table = arguments->argumentAt(0); |
| + ScriptValue columns = arguments->argumentCount() > 1 ? arguments->argumentAt(1) : ScriptValue(); |
| + RefPtr<TypeBuilder::Runtime::RemoteObject> inspectorValue = injectedScript.wrapTable(table, columns); |
| + if (!inspectorValue) { |
| + ASSERT_NOT_REACHED(); |
| + return; |
| + } |
| + jsonArgs->addItem(inspectorValue); |
| + } else { |
| + for (unsigned i = 0; i < arguments->argumentCount(); ++i) { |
| + RefPtr<TypeBuilder::Runtime::RemoteObject> inspectorValue = injectedScript.wrapObject(arguments->argumentAt(i), "console", generatePreview); |
| + if (!inspectorValue) { |
| + ASSERT_NOT_REACHED(); |
| + return; |
| + } |
| + jsonArgs->addItem(inspectorValue); |
| + } |
| + } |
| + jsonObj->setParameters(jsonArgs); |
| + } |
| + } |
| + if (consoleMessage->callStack()) { |
| + jsonObj->setStackTrace(consoleMessage->callStack()->buildInspectorArray()); |
| + RefPtrWillBeRawPtr<ScriptAsyncCallStack> asyncCallStack = consoleMessage->callStack()->asyncCallStack(); |
| + if (asyncCallStack) |
| + jsonObj->setAsyncStackTrace(asyncCallStack->buildInspectorObject()); |
| } |
| + m_frontend->messageAdded(jsonObj); |
| + m_frontend->flush(); |
| } |
| class InspectableHeapObject FINAL : public InjectedScriptHost::InspectableObject { |